#include <vnet/fib/ip4_fib.h>
#include <vnet/ip/reass/ip4_sv_reass.h>
#include <vppinfra/bihash_16_8.h>
+#include <nat/nat44/ed_inlines.h>
#include <vpp/app/version.h>
if (snat_is_unk_proto_session (s))
{
make_ed_kv (&s->in2out.addr, &s->ext_host_addr, s->in2out.port, 0,
- 0, 0, ~0ULL, &ed_kv);
+ 0, 0, ~0, ~0, &ed_kv);
}
else
{
- proto = snat_proto_to_ip_proto (s->in2out.protocol);
l_port = s->in2out.port;
r_port = s->ext_host_port;
l_addr = &s->in2out.addr;
r_addr = &s->ext_host_addr;
- proto = snat_proto_to_ip_proto (s->in2out.protocol);
- make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0ULL,
- &ed_kv);
+ proto = nat_proto_to_ip_proto (s->in2out.protocol);
+ make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0,
+ ~0, &ed_kv);
}
if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0))
nat_elog_warn ("in2out_ed key del failed");
}
else
{
- proto = snat_proto_to_ip_proto (s->in2out.protocol);
+ proto = nat_proto_to_ip_proto (s->in2out.protocol);
l_port = s->out2in.port;
r_port = s->ext_host_port;
}
- make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0ULL,
+ make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0,
&ed_kv);
- if (clib_bihash_add_del_16_8 (&tsm->out2in_ed, &ed_kv, 0))
+ if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &ed_kv, 0))
nat_elog_warn ("out2in_ed key del failed");
l_addr = &s->in2out.addr;
fib_index = s->in2out.fib_index;
r_addr = &s->ext_host_nat_addr;
r_port = s->ext_host_nat_port;
}
- make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0ULL,
+ make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0,
&ed_kv);
if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0))
nat_elog_warn ("in2out_ed key del failed");
return 0;
}
-
void
nat44_free_session_data (snat_main_t * sm, snat_session_t * s,
u32 thread_index, u8 is_ha)
}
else
{
- proto = snat_proto_to_ip_proto (s->in2out.protocol);
+ proto = nat_proto_to_ip_proto (s->in2out.protocol);
l_port = s->in2out.port;
r_port = s->ext_host_port;
}
l_addr = &s->in2out.addr;
r_addr = &s->ext_host_addr;
fib_index = 0;
- make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0ULL,
+ make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0,
&ed_kv);
if (PREDICT_FALSE
}
else
{
- proto = snat_proto_to_ip_proto (s->in2out.protocol);
+ proto = nat_proto_to_ip_proto (s->in2out.protocol);
l_port = s->out2in.port;
r_port = s->ext_host_port;
}
- make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0ULL,
+ make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0,
&ed_kv);
- if (PREDICT_FALSE (clib_bihash_add_del_16_8 (&tsm->out2in_ed, &ed_kv, 0)))
+ if (PREDICT_FALSE (clib_bihash_add_del_16_8 (&sm->out2in_ed, &ed_kv, 0)))
nat_elog_warn ("out2in_ed key del failed");
l_addr = &s->in2out.addr;
r_addr = &s->ext_host_nat_addr;
r_port = s->ext_host_nat_port;
}
- make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0ULL,
+ make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0, ~0,
&ed_kv);
if (PREDICT_FALSE (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0)))
if (snat_is_unk_proto_session (s))
return;
- // is this correct ?
if (!is_ha)
{
snat_ipfix_logging_nat44_ses_delete (thread_index,
if (snat_is_session_static (s))
return;
- // should be called for every dynamic session
snat_free_outside_address_and_port (sm->addresses, thread_index,
&s->out2in);
}
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));
return s;
}
-int
-nat_global_lru_free_one (snat_main_t * sm, int thread_index, f64 now)
-{
- snat_session_t *s = NULL;
- dlist_elt_t *oldest_elt;
- u64 sess_timeout_time;
- u32 oldest_index;
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
- 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);
- return 1;
- }
- else
- {
- clib_dlist_addhead (tsm->global_lru_pool,
- tsm->global_lru_head_index, oldest_index);
- }
- }
- return 0;
-}
-
-snat_session_t *
-nat_ed_session_alloc (snat_main_t * sm, u32 thread_index, f64 now)
-{
- snat_session_t *s;
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
-
- nat_global_lru_free_one (sm, thread_index, now);
-
- pool_get (tsm->sessions, s);
- clib_memset (s, 0, sizeof (*s));
-
- nat44_global_lru_insert (tsm, s, now);
-
- s->ha_last_refreshed = now;
- vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
- pool_elts (tsm->sessions));
- return s;
-}
-
void
snat_add_del_addr_to_fib (ip4_address_t * addr, u8 p_len, u32 sw_if_index,
int is_add)
ap->busy_##n##_ports = 0; \
ap->busy_##n##_ports_per_thread = 0;\
vec_validate_init_empty (ap->busy_##n##_ports_per_thread, tm->n_vlib_mains - 1, 0);
- foreach_snat_protocol
+ foreach_nat_protocol
#undef _
if (twice_nat)
return 0;
u32 sw_if_index,
u16 e_port,
u32 vrf_id,
- snat_protocol_t proto,
+ nat_protocol_t proto,
int addr_only, int is_add, u8 * tag,
int twice_nat, int out2in_only,
int identity_nat)
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);
+ nat_ed_session_delete (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,
- u32 sw_if_index, snat_protocol_t proto, int is_add,
+ u32 sw_if_index, nat_protocol_t proto, int is_add,
twice_nat_type_t twice_nat, u8 out2in_only, u8 * tag,
u8 identity_nat)
{
switch (proto)
{
#define _(N, j, n, s) \
- case SNAT_PROTOCOL_##N: \
+ case NAT_PROTOCOL_##N: \
if (a->busy_##n##_port_refcounts[e_port]) \
return VNET_API_ERROR_INVALID_VALUE; \
++a->busy_##n##_port_refcounts[e_port]; \
a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]++; \
} \
break;
- foreach_snat_protocol
+ foreach_nat_protocol
#undef _
default:
nat_elog_info ("unknown protocol");
switch (proto)
{
#define _(N, j, n, s) \
- case SNAT_PROTOCOL_##N: \
+ case NAT_PROTOCOL_##N: \
--a->busy_##n##_port_refcounts[e_port]; \
if (e_port > 1024) \
{ \
a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]--; \
} \
break;
- foreach_snat_protocol
+ foreach_nat_protocol
#undef _
default:
nat_elog_info ("unknown protocol");
int
nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
- snat_protocol_t proto,
+ nat_protocol_t proto,
nat44_lb_addr_port_t * locals, u8 is_add,
twice_nat_type_t twice_nat, u8 out2in_only,
u8 * tag, u32 affinity)
switch (proto)
{
#define _(N, j, n, s) \
- case SNAT_PROTOCOL_##N: \
+ case NAT_PROTOCOL_##N: \
if (a->busy_##n##_port_refcounts[e_port]) \
return VNET_API_ERROR_INVALID_VALUE; \
++a->busy_##n##_port_refcounts[e_port]; \
a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]++; \
} \
break;
- foreach_snat_protocol
+ foreach_nat_protocol
#undef _
default:
nat_elog_info ("unknown protocol");
switch (proto)
{
#define _(N, j, n, s) \
- case SNAT_PROTOCOL_##N: \
+ case NAT_PROTOCOL_##N: \
--a->busy_##n##_port_refcounts[e_port]; \
if (e_port > 1024) \
{ \
a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]--; \
} \
break;
- foreach_snat_protocol
+ foreach_nat_protocol
#undef _
default:
nat_elog_info ("unknown protocol");
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);
+ nat_ed_session_delete (sm, s, tsm - sm->per_thread_data, 1);
});
}));
/* *INDENT-ON* */
int
nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
ip4_address_t l_addr, u16 l_port,
- snat_protocol_t proto, u32 vrf_id,
+ nat_protocol_t proto, u32 vrf_id,
u8 probability, u8 is_add)
{
snat_main_t *sm = &snat_main;
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);
+ nat_ed_session_delete (sm, s, tsm - sm->per_thread_data, 1);
});
/* *INDENT-ON* */
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);
+ nat_ed_session_delete (sm, ses, tsm - sm->per_thread_data, 1);
}
}else{
vec_foreach (ses_index, ses_to_be_removed)
#define _(N, i, n, s) \
vec_free (a->busy_##n##_ports_per_thread);
- foreach_snat_protocol
+ foreach_nat_protocol
#undef _
if (twice_nat)
{
if (sm->fq_in2out_index == ~0 && !sm->deterministic && sm->num_workers > 1)
sm->fq_in2out_index =
- vlib_frame_queue_main_init (sm->handoff_in2out_index, NAT_FQ_NELTS);
+ vlib_frame_queue_main_init (sm->in2out_node_index, NAT_FQ_NELTS);
if (sm->fq_out2in_index == ~0 && !sm->deterministic && sm->num_workers > 1)
sm->fq_out2in_index =
- vlib_frame_queue_main_init (sm->handoff_out2in_index, NAT_FQ_NELTS);
+ vlib_frame_queue_main_init (sm->out2in_node_index, NAT_FQ_NELTS);
if (!is_inside)
{
fq:
if (sm->fq_in2out_output_index == ~0 && sm->num_workers > 1)
sm->fq_in2out_output_index =
- vlib_frame_queue_main_init (sm->handoff_in2out_output_index, 0);
+ vlib_frame_queue_main_init (sm->in2out_output_node_index, 0);
if (sm->fq_out2in_index == ~0 && sm->num_workers > 1)
sm->fq_out2in_index =
- vlib_frame_queue_main_init (sm->handoff_out2in_index, 0);
+ vlib_frame_queue_main_init (sm->out2in_node_index, 0);
/* *INDENT-OFF* */
pool_foreach (i, sm->output_feature_interfaces,
/* *INDENT-ON* */
sm->port_per_thread = (0xffff - 1024) / _vec_len (sm->workers);
- sm->num_snat_thread = _vec_len (sm->workers);
return 0;
}
u16 r_port = 40301;
u8 proto = 9;
u32 fib_index = 9000001;
- u64 value = ~0ULL;
+ u32 thread_index = 3000000001;
+ u32 session_index = 3000000221;
clib_bihash_kv_16_8_t kv;
- make_ed_kv (&l_addr, &r_addr, proto, fib_index, l_port, r_port, value, &kv);
+ make_ed_kv (&l_addr, &r_addr, proto, fib_index, l_port, r_port,
+ thread_index, session_index, &kv);
ip4_address_t l_addr2;
ip4_address_t r_addr2;
clib_memset (&l_addr2, 0, sizeof (l_addr2));
u32 fib_index2 = 0;
split_ed_kv (&kv, &l_addr2, &r_addr2, &proto2, &fib_index2, &l_port2,
&r_port2);
- u64 value2 = kv.value;
ASSERT (l_addr.as_u32 == l_addr2.as_u32);
ASSERT (r_addr.as_u32 == r_addr2.as_u32);
ASSERT (l_port == l_port2);
ASSERT (r_port == r_port2);
ASSERT (proto == proto2);
ASSERT (fib_index == fib_index2);
- ASSERT (value == value2);
+ ASSERT (thread_index == ed_value_get_thread_index (&kv));
+ ASSERT (session_index == ed_value_get_session_index (&kv));
}
static clib_error_t *
ip4_add_del_interface_address_callback_t cb4;
vlib_node_t *node;
- sm->vlib_main = vm;
sm->vnet_main = vnet_get_main ();
sm->ip4_main = im;
sm->ip4_lookup_main = lm;
sm->api_main = vlibapi_get_main ();
sm->first_worker_index = 0;
sm->num_workers = 0;
- sm->num_snat_thread = 1;
sm->workers = 0;
sm->port_per_thread = 0xffff - 1024;
sm->fq_in2out_index = ~0;
switch (k->protocol)
{
#define _(N, i, n, s) \
- case SNAT_PROTOCOL_##N: \
+ case NAT_PROTOCOL_##N: \
ASSERT (a->busy_##n##_port_refcounts[port_host_byte_order] >= 1); \
--a->busy_##n##_port_refcounts[port_host_byte_order]; \
a->busy_##n##_ports--; \
a->busy_##n##_ports_per_thread[thread_index]--; \
break;
- foreach_snat_protocol
+ foreach_nat_protocol
#undef _
default:
nat_elog_info ("unknown protocol");
switch (k->protocol)
{
#define _(N, j, n, s) \
- case SNAT_PROTOCOL_##N: \
+ case NAT_PROTOCOL_##N: \
if (a->busy_##n##_port_refcounts[port_host_byte_order]) \
return VNET_API_ERROR_INSTANCE_IN_USE; \
++a->busy_##n##_port_refcounts[port_host_byte_order]; \
a->busy_##n##_ports_per_thread[thread_index]++; \
a->busy_##n##_ports++; \
return 0;
- foreach_snat_protocol
+ foreach_nat_protocol
#undef _
default:
nat_elog_info ("unknown protocol");
switch (k->protocol)
{
#define _(N, j, n, s) \
- case SNAT_PROTOCOL_##N: \
+ case NAT_PROTOCOL_##N: \
if (a->busy_##n##_ports_per_thread[thread_index] < port_per_thread) \
{ \
if (a->fib_index == fib_index) \
} \
} \
break;
- foreach_snat_protocol
+ foreach_nat_protocol
#undef _
default:
nat_elog_info ("unknown protocol");
switch (k->protocol)
{
#define _(N, j, n, s) \
- case SNAT_PROTOCOL_##N: \
+ case NAT_PROTOCOL_##N: \
while (1) \
{ \
portnum = (port_per_thread * \
return 0; \
}
break;
- foreach_snat_protocol
+ foreach_nat_protocol
#undef _
default:
nat_elog_info ("unknown protocol");
switch (k->protocol)
{
#define _(N, i, n, s) \
- case SNAT_PROTOCOL_##N: \
+ case NAT_PROTOCOL_##N: \
if (a->busy_##n##_ports < ports) \
{ \
while (1) \
} \
} \
break;
- foreach_snat_protocol
+ foreach_nat_protocol
#undef _
default:
nat_elog_info ("unknown protocol");
switch (k->protocol)
{
#define _(N, i, n, s) \
- case SNAT_PROTOCOL_##N: \
+ case NAT_PROTOCOL_##N: \
if (a->busy_##n##_ports < ports) \
{ \
while (1) \
} \
} \
break;
- foreach_snat_protocol
+ foreach_nat_protocol
#undef _
default:
nat_elog_info ("unknown protocol");
split_ed_kv (v, &l_addr, &r_addr, &proto, &fib_index, &l_port, &r_port);
s =
- format (s, "local %U:%d remote %U:%d proto %U fib %d session-index %llu",
+ format (s,
+ "local %U:%d remote %U:%d proto %U fib %d thread-index %u session-index %u",
format_ip4_address, &l_addr, clib_net_to_host_u16 (l_port),
format_ip4_address, &r_addr, clib_net_to_host_u16 (r_port),
- format_ip_protocol, proto, fib_index, v->value);
+ format_ip_protocol, proto, fib_index,
+ ed_value_get_session_index (v), ed_value_get_thread_index (v));
return s;
}
}
}
- proto = ip_proto_to_snat_proto (ip0->protocol);
+ proto = ip_proto_to_nat_proto (ip0->protocol);
udp = ip4_next_header (ip0);
port = udp->dst_port;
/* unknown protocol */
- if (PREDICT_FALSE (proto == ~0))
+ if (PREDICT_FALSE (proto == NAT_PROTOCOL_OTHER))
{
/* use current thread */
return vlib_get_thread_index ();
{
/* if error message, then it's not fragmented and we can access it */
ip4_header_t *inner_ip = (ip4_header_t *) (echo + 1);
- proto = ip_proto_to_snat_proto (inner_ip->protocol);
+ proto = ip_proto_to_nat_proto (inner_ip->protocol);
void *l4_header = ip4_next_header (inner_ip);
switch (proto)
{
- case SNAT_PROTOCOL_ICMP:
+ case NAT_PROTOCOL_ICMP:
icmp = (icmp46_header_t *) l4_header;
echo = (icmp_echo_header_t *) (icmp + 1);
port = echo->identifier;
break;
- case SNAT_PROTOCOL_UDP:
- case SNAT_PROTOCOL_TCP:
+ case NAT_PROTOCOL_UDP:
+ case NAT_PROTOCOL_TCP:
port = ((tcp_udp_header_t *) l4_header)->src_port;
break;
default:
make_ed_kv (&ip->src_address, &ip->dst_address,
ip->protocol, fib_index, udp->src_port, udp->dst_port,
- ~0ULL, &kv16);
-
- /* *INDENT-OFF* */
- vec_foreach (tsm, sm->per_thread_data)
- {
- if (PREDICT_TRUE (!clib_bihash_search_16_8 (&tsm->out2in_ed,
- &kv16, &value16)))
- {
- next_worker_index += tsm->thread_index;
+ ~0, ~0, &kv16);
- nat_elog_debug_handoff (
- "HANDOFF IN2OUT-OUTPUT-FEATURE (session)",
- next_worker_index, fib_index,
- clib_net_to_host_u32 (ip->src_address.as_u32),
- clib_net_to_host_u32 (ip->dst_address.as_u32));
-
- return next_worker_index;
- }
- }
- /* *INDENT-ON* */
+ if (PREDICT_TRUE (!clib_bihash_search_16_8 (&sm->out2in_ed,
+ &kv16, &value16)))
+ {
+ tsm =
+ vec_elt_at_index (sm->per_thread_data,
+ ed_value_get_thread_index (&value16));
+ next_worker_index += tsm->thread_index;
+
+ nat_elog_debug_handoff ("HANDOFF IN2OUT-OUTPUT-FEATURE (session)",
+ next_worker_index, fib_index,
+ clib_net_to_host_u32 (ip->
+ src_address.as_u32),
+ clib_net_to_host_u32 (ip->
+ dst_address.as_u32));
+
+ return next_worker_index;
+ }
}
hash = ip->src_address.as_u32 + (ip->src_address.as_u32 >> 8) +
snat_static_mapping_t *m;
u32 hash;
- proto = ip_proto_to_snat_proto (ip->protocol);
+ proto = ip_proto_to_nat_proto (ip->protocol);
- if (PREDICT_TRUE (proto == SNAT_PROTOCOL_UDP || proto == SNAT_PROTOCOL_TCP))
+ if (PREDICT_TRUE (proto == NAT_PROTOCOL_UDP || proto == NAT_PROTOCOL_TCP))
{
udp = ip4_next_header (ip);
make_ed_kv (&ip->dst_address, &ip->src_address,
ip->protocol, rx_fib_index, udp->dst_port, udp->src_port,
- ~0ULL, &kv16);
+ ~0, ~0, &kv16);
- /* *INDENT-OFF* */
- vec_foreach (tsm, sm->per_thread_data)
- {
- if (PREDICT_TRUE (!clib_bihash_search_16_8 (&tsm->out2in_ed,
- &kv16, &value16)))
- {
- next_worker_index = sm->first_worker_index + tsm->thread_index;
- nat_elog_debug_handoff ("HANDOFF OUT2IN (session)",
- next_worker_index, rx_fib_index,
- clib_net_to_host_u32 (ip->src_address.as_u32),
- clib_net_to_host_u32 (ip->dst_address.as_u32));
- return next_worker_index;
- }
- }
- /* *INDENT-ON* */
+ if (PREDICT_TRUE (!clib_bihash_search_16_8 (&sm->out2in_ed,
+ &kv16, &value16)))
+ {
+ tsm =
+ vec_elt_at_index (sm->per_thread_data,
+ ed_value_get_thread_index (&value16));
+ vnet_buffer2 (b)->nat.ed_out2in_nat_session_index =
+ ed_value_get_session_index (&value16);
+ next_worker_index = sm->first_worker_index + tsm->thread_index;
+ nat_elog_debug_handoff ("HANDOFF OUT2IN (session)",
+ next_worker_index, rx_fib_index,
+ clib_net_to_host_u32 (ip->
+ src_address.as_u32),
+ clib_net_to_host_u32 (ip->
+ dst_address.as_u32));
+ return next_worker_index;
+ }
}
- else if (proto == SNAT_PROTOCOL_ICMP)
+ else if (proto == NAT_PROTOCOL_ICMP)
{
- if (!get_icmp_o2i_ed_key (b, ip, rx_fib_index, ~0ULL, 0, 0, 0, &kv16))
+ if (!get_icmp_o2i_ed_key (b, ip, rx_fib_index, ~0, ~0, 0, 0, 0, &kv16))
{
- /* *INDENT-OFF* */
- vec_foreach (tsm, sm->per_thread_data)
- {
- if (PREDICT_TRUE (!clib_bihash_search_16_8 (&tsm->out2in_ed,
- &kv16, &value16)))
- {
- next_worker_index = sm->first_worker_index +
- tsm->thread_index;
- nat_elog_debug_handoff ("HANDOFF OUT2IN (session)",
- next_worker_index, rx_fib_index,
- clib_net_to_host_u32 (ip->src_address.as_u32),
- clib_net_to_host_u32 (ip->dst_address.as_u32));
- return next_worker_index;
- }
- }
- /* *INDENT-ON* */
+ if (PREDICT_TRUE (!clib_bihash_search_16_8 (&sm->out2in_ed,
+ &kv16, &value16)))
+ {
+ tsm =
+ vec_elt_at_index (sm->per_thread_data,
+ ed_value_get_thread_index (&value16));
+ next_worker_index = sm->first_worker_index + tsm->thread_index;
+ nat_elog_debug_handoff ("HANDOFF OUT2IN (session)",
+ next_worker_index, rx_fib_index,
+ clib_net_to_host_u32 (ip->
+ src_address.as_u32),
+ clib_net_to_host_u32 (ip->
+ dst_address.as_u32));
+ return next_worker_index;
+ }
}
}
}
/* unknown protocol */
- if (PREDICT_FALSE (proto == ~0))
+ if (PREDICT_FALSE (proto == NAT_PROTOCOL_OTHER))
{
/* use current thread */
next_worker_index = vlib_get_thread_index ();
{
/* if error message, then it's not fragmented and we can access it */
ip4_header_t *inner_ip = (ip4_header_t *) (echo + 1);
- proto = ip_proto_to_snat_proto (inner_ip->protocol);
+ proto = ip_proto_to_nat_proto (inner_ip->protocol);
void *l4_header = ip4_next_header (inner_ip);
switch (proto)
{
- case SNAT_PROTOCOL_ICMP:
+ case NAT_PROTOCOL_ICMP:
icmp = (icmp46_header_t *) l4_header;
echo = (icmp_echo_header_t *) (icmp + 1);
port = echo->identifier;
break;
- case SNAT_PROTOCOL_UDP:
- case SNAT_PROTOCOL_TCP:
+ case NAT_PROTOCOL_UDP:
+ case NAT_PROTOCOL_TCP:
port = ((tcp_udp_header_t *) l4_header)->src_port;
break;
default:
u32 fib_index, u16 flags, u32 thread_index)
{
snat_main_t *sm = &snat_main;
+ snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
snat_session_key_t key;
snat_user_t *u;
snat_session_t *s;
clib_bihash_kv_8_8_t kv;
- f64 now = vlib_time_now (sm->vlib_main);
+ vlib_main_t *vm = vlib_get_main ();
+ f64 now = vlib_time_now (vm);
nat_outside_fib_t *outside_fib;
fib_node_index_t fei = FIB_NODE_INDEX_INVALID;
- snat_main_per_thread_data_t *tsm;
fib_prefix_t pfx = {
.fp_proto = FIB_PROTOCOL_IP4,
.fp_len = 32,
},
};
- tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
-
key.addr.as_u32 = out_addr->as_u32;
key.port = out_port;
key.protocol = proto;
if (!s)
return;
+ if (sm->endpoint_dependent)
+ {
+ nat_ed_lru_insert (tsm, s, now, proto);
+ }
+
s->last_heard = now;
s->flags = flags;
s->ext_host_addr.as_u32 = eh_addr->as_u32;
u32 fib_index, u16 flags, u32 thread_index)
{
snat_main_t *sm = &snat_main;
+ snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
snat_session_key_t key;
snat_session_t *s;
clib_bihash_kv_16_8_t kv;
- f64 now = vlib_time_now (sm->vlib_main);
+ vlib_main_t *vm = vlib_get_main ();
+ f64 now = vlib_time_now (vm);
nat_outside_fib_t *outside_fib;
fib_node_index_t fei = FIB_NODE_INDEX_INVALID;
- snat_main_per_thread_data_t *tsm;
fib_prefix_t pfx = {
.fp_proto = FIB_PROTOCOL_IP4,
.fp_len = 32,
},
};
- tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
-
key.addr.as_u32 = out_addr->as_u32;
key.port = out_port;
key.protocol = proto;
return;
}
- s = nat_ed_session_alloc (sm, thread_index, now);
+ s = nat_ed_session_alloc (sm, thread_index, now, proto);
if (!s)
return;
s->in2out = key;
make_ed_kv (in_addr, &s->ext_host_nat_addr,
- snat_proto_to_ip_proto (proto), fib_index, in_port,
- s->ext_host_nat_port, s - tsm->sessions, &kv);
+ nat_proto_to_ip_proto (proto), fib_index, in_port,
+ s->ext_host_nat_port, thread_index, s - tsm->sessions, &kv);
if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &kv, 1))
nat_elog_warn ("in2out key add failed");
- make_ed_kv (out_addr, eh_addr, snat_proto_to_ip_proto (proto),
- s->out2in.fib_index, out_port, eh_port, s - tsm->sessions, &kv);
- if (clib_bihash_add_del_16_8 (&tsm->out2in_ed, &kv, 1))
+ make_ed_kv (out_addr, eh_addr, nat_proto_to_ip_proto (proto),
+ s->out2in.fib_index, out_port, eh_port, thread_index,
+ s - tsm->sessions, &kv);
+ if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &kv, 1))
nat_elog_warn ("out2in key add failed");
}
thread_index = sm->num_workers;
tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
- make_ed_kv (out_addr, eh_addr, proto, fib_index, out_port, eh_port, ~0ULL,
+ make_ed_kv (out_addr, eh_addr, proto, fib_index, out_port, eh_port, ~0, ~0,
&kv);
- if (clib_bihash_search_16_8 (&tsm->out2in_ed, &kv, &value))
+ if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
return;
- s = pool_elt_at_index (tsm->sessions, value.value);
+ s = pool_elt_at_index (tsm->sessions, ed_value_get_session_index (&value));
nat_free_session_data (sm, s, thread_index, 1);
nat44_delete_session (sm, s, thread_index);
}
tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
- make_ed_kv (out_addr, eh_addr, proto, fib_index, out_port, eh_port, ~0ULL,
+ make_ed_kv (out_addr, eh_addr, proto, fib_index, out_port, eh_port, ~0, ~0,
&kv);
- if (clib_bihash_search_16_8 (&tsm->out2in_ed, &kv, &value))
+ if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
return;
- s = pool_elt_at_index (tsm->sessions, value.value);
+ s = pool_elt_at_index (tsm->sessions, ed_value_get_session_index (&value));
s->total_pkts = total_pkts;
s->total_bytes = total_bytes;
}
snat_main_t *sm = &snat_main;
pool_alloc (tsm->sessions, sm->max_translations);
- pool_alloc (tsm->global_lru_pool, sm->max_translations);
+ pool_alloc (tsm->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);
+
+ pool_get (tsm->lru_pool, head);
+ tsm->tcp_trans_lru_head_index = head - tsm->lru_pool;
+ clib_dlist_init (tsm->lru_pool, tsm->tcp_trans_lru_head_index);
+
+ pool_get (tsm->lru_pool, head);
+ tsm->tcp_estab_lru_head_index = head - tsm->lru_pool;
+ clib_dlist_init (tsm->lru_pool, tsm->tcp_estab_lru_head_index);
+
+ pool_get (tsm->lru_pool, head);
+ tsm->udp_lru_head_index = head - tsm->lru_pool;
+ clib_dlist_init (tsm->lru_pool, tsm->udp_lru_head_index);
+
+ pool_get (tsm->lru_pool, head);
+ tsm->icmp_lru_head_index = head - tsm->lru_pool;
+ clib_dlist_init (tsm->lru_pool, tsm->icmp_lru_head_index);
+
+ pool_get (tsm->lru_pool, head);
+ tsm->unk_proto_lru_head_index = head - tsm->lru_pool;
+ clib_dlist_init (tsm->lru_pool, tsm->unk_proto_lru_head_index);
if (sm->endpoint_dependent)
{
sm->translation_memory_size);
clib_bihash_set_kvp_format_fn_16_8 (&tsm->in2out_ed,
format_ed_session_kvp);
- clib_bihash_init_16_8 (&tsm->out2in_ed, "out2in-ed",
- sm->translation_buckets,
- sm->translation_memory_size);
- clib_bihash_set_kvp_format_fn_16_8 (&tsm->out2in_ed,
- format_ed_session_kvp);
}
else
{
snat_main_t *sm = &snat_main;
pool_free (tsm->sessions);
- pool_free (tsm->global_lru_pool);
+ pool_free (tsm->lru_pool);
if (sm->endpoint_dependent)
{
clib_bihash_free_16_8 (&tsm->in2out_ed);
- clib_bihash_free_16_8 (&tsm->out2in_ed);
}
else
{
clib_bihash_free_8_8 (&tsm->user_hash);
}
+void
+nat44_sessions_clear ()
+{
+ snat_main_t *sm = &snat_main;
+ snat_main_per_thread_data_t *tsm;
+
+ if (sm->endpoint_dependent)
+ {
+ clib_bihash_free_16_8 (&sm->out2in_ed);
+ clib_bihash_init_16_8 (&sm->out2in_ed, "out2in-ed",
+ clib_max (1, sm->num_workers) *
+ sm->translation_buckets,
+ clib_max (1, sm->num_workers) *
+ sm->translation_memory_size);
+ clib_bihash_set_kvp_format_fn_16_8 (&sm->out2in_ed,
+ format_ed_session_kvp);
+ }
+
+ /* *INDENT-OFF* */
+ vec_foreach (tsm, sm->per_thread_data)
+ {
+ u32 ti;
+
+ nat44_db_free (tsm);
+ nat44_db_init (tsm);
+
+ ti = tsm->snat_thread_index;
+ vlib_set_simple_counter (&sm->total_users, ti, 0, 0);
+ vlib_set_simple_counter (&sm->total_sessions, ti, 0, 0);
+ }
+ /* *INDENT-ON* */
+}
+
static clib_error_t *
snat_config (vlib_main_t * vm, unformat_input_t * input)
{
snat_main_t *sm = &snat_main;
nat66_main_t *nm = &nat66_main;
- //dslite_main_t *dm = &dslite_main;
snat_main_per_thread_data_t *tsm;
u32 static_mapping_buckets = 1024;
u8 static_mapping_only = 0;
u8 static_mapping_connection_tracking = 0;
- // configurable timeouts
u32 udp_timeout = SNAT_UDP_TIMEOUT;
u32 icmp_timeout = SNAT_ICMP_TIMEOUT;
u32 tcp_transitory_timeout = SNAT_TCP_TRANSITORY_TIMEOUT;
;
else if (unformat (input, "out2in dpo"))
sm->out2in_dpo = 1;
- //else if (unformat (input, "dslite ce"))
- //dslite_set_ce (dm, 1);
else if (unformat (input, "endpoint-dependent"))
sm->endpoint_dependent = 1;
else
sm->worker_in2out_cb = nat44_ed_get_worker_in2out_cb;
sm->worker_out2in_cb = nat44_ed_get_worker_out2in_cb;
- sm->handoff_out2in_index = nat_pre_out2in_node.index;
- sm->handoff_in2out_index = nat_pre_in2out_node.index;
- sm->handoff_in2out_output_index = nat44_ed_in2out_output_node.index;
-
sm->in2out_node_index = nat44_ed_in2out_node.index;
sm->in2out_output_node_index = nat44_ed_in2out_output_node.index;
sm->out2in_node_index = nat44_ed_out2in_node.index;
nat_affinity_init (vm);
nat_ha_init (vm, nat_ha_sadd_ed_cb, nat_ha_sdel_ed_cb,
nat_ha_sref_ed_cb);
+ clib_bihash_init_16_8 (&sm->out2in_ed, "out2in-ed",
+ translation_buckets,
+ translation_memory_size);
+ clib_bihash_set_kvp_format_fn_16_8 (&sm->out2in_ed,
+ format_ed_session_kvp);
}
else
{
sm->worker_in2out_cb = snat_get_worker_in2out_cb;
sm->worker_out2in_cb = snat_get_worker_out2in_cb;
- sm->handoff_out2in_index = snat_out2in_node.index;
- sm->handoff_in2out_index = snat_in2out_node.index;
- sm->handoff_in2out_output_index = snat_in2out_output_node.index;
-
sm->in2out_node_index = snat_in2out_node.index;
sm->in2out_output_node_index = snat_in2out_output_node.index;
sm->out2in_node_index = snat_out2in_node.index;
+
sm->icmp_match_in2out_cb = icmp_match_in2out_slow;
sm->icmp_match_out2in_cb = icmp_match_out2in_slow;
nat_ha_init (vm, nat_ha_sadd_cb, nat_ha_sdel_cb, nat_ha_sref_cb);
int
nat44_del_session (snat_main_t * sm, ip4_address_t * addr, u16 port,
- snat_protocol_t proto, u32 vrf_id, int is_in)
+ nat_protocol_t proto, u32 vrf_id, int is_in)
{
snat_main_per_thread_data_t *tsm;
clib_bihash_kv_8_8_t kv, value;
else
tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
- t = is_in ? &tsm->in2out_ed : &tsm->out2in_ed;
+ t = is_in ? &tsm->in2out_ed : &sm->out2in_ed;
make_ed_kv (addr, eh_addr, proto, fib_index, clib_host_to_net_u16 (port),
- clib_host_to_net_u16 (eh_port), ~0ULL, &kv);
+ clib_host_to_net_u16 (eh_port), ~0, ~0, &kv);
if (clib_bihash_search_16_8 (t, &kv, &value))
{
return VNET_API_ERROR_NO_SUCH_ENTRY;
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_ed_delete_session (sm, s, tsm - sm->per_thread_data, 1);
+ nat_ed_session_delete (sm, s, tsm - sm->per_thread_data, 1);
return 0;
}
.next_nodes = {
[NAT_NEXT_DROP] = "error-drop",
[NAT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
- [NAT_NEXT_IN2OUT_PRE] = "nat-pre-in2out",
- [NAT_NEXT_OUT2IN_PRE] = "nat-pre-out2in",
[NAT_NEXT_IN2OUT_ED_FAST_PATH] = "nat44-ed-in2out",
[NAT_NEXT_IN2OUT_ED_SLOW_PATH] = "nat44-ed-in2out-slowpath",
[NAT_NEXT_IN2OUT_ED_OUTPUT_SLOW_PATH] = "nat44-ed-in2out-output-slowpath",
[NAT_NEXT_OUT2IN_ED_FAST_PATH] = "nat44-ed-out2in",
[NAT_NEXT_OUT2IN_ED_SLOW_PATH] = "nat44-ed-out2in-slowpath",
+ [NAT_NEXT_IN2OUT_CLASSIFY] = "nat44-in2out-worker-handoff",
+ [NAT_NEXT_OUT2IN_CLASSIFY] = "nat44-out2in-worker-handoff",
},
};
/* *INDENT-ON* */