snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data,
ctx->thread_index);
- s = pool_elt_at_index (tsm->sessions, kv->value);
+ ASSERT (ctx->thread_index == ed_value_get_thread_index (kv));
+ s = pool_elt_at_index (tsm->sessions, ed_value_get_session_index (kv));
sess_timeout_time = s->last_heard + (f64) nat44_session_get_timeout (sm, s);
if (ctx->now >= sess_timeout_time)
{
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");
if (snat_is_unk_proto_session (s))
--attempts; \
portnum = port_thread_offset + port; \
make_ed_kv (&a->addr, &r_addr, proto, s->out2in.fib_index, \
- clib_host_to_net_u16 (portnum), r_port, \
+ clib_host_to_net_u16 (portnum), r_port, thread_index, \
s - tsm->sessions, out2in_ed_kv); \
- int rv = clib_bihash_add_del_16_8 (&tsm->out2in_ed, out2in_ed_kv, \
+ int rv = clib_bihash_add_del_16_8 (&sm->out2in_ed, out2in_ed_kv, \
2 /* is_add */); \
if (0 == rv) \
{ \
make_ed_kv (&key1.addr, &r_addr, proto,
- s->out2in.fib_index, key1.port, r_port, s - tsm->sessions,
- &out2in_ed_kv);
+ s->out2in.fib_index, key1.port, r_port, thread_index,
+ s - tsm->sessions, &out2in_ed_kv);
if (clib_bihash_add_or_overwrite_stale_16_8
- (&tsm->out2in_ed, &out2in_ed_kv, nat44_o2i_ed_is_idle_session_cb,
+ (&sm->out2in_ed, &out2in_ed_kv, nat44_o2i_ed_is_idle_session_cb,
&ctx))
nat_elog_notice ("out2in-ed key add failed");
}
clib_bihash_kv_16_8_t in2out_ed_kv;
make_ed_kv (&l_addr, &r_addr, proto, rx_fib_index, l_port, r_port,
- s - tsm->sessions, &in2out_ed_kv);
+ thread_index, s - tsm->sessions, &in2out_ed_kv);
ctx.now = now;
ctx.thread_index = thread_index;
if (clib_bihash_add_or_overwrite_stale_16_8 (&tsm->in2out_ed, &in2out_ed_kv,
u32 rx_fib_index, u32 thread_index)
{
udp_header_t *udp = ip4_next_header (ip);
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
clib_bihash_kv_16_8_t kv, value;
snat_session_key_t key0, key1;
make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol,
- sm->outside_fib_index, udp->dst_port, udp->src_port, ~0ULL,
+ sm->outside_fib_index, udp->dst_port, udp->src_port, ~0, ~0,
&kv);
/* NAT packet aimed at external address if has active sessions */
- if (clib_bihash_search_16_8 (&tsm->out2in_ed, &kv, &value))
+ if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
{
key0.addr = ip->dst_address;
key0.port = udp->dst_port;
if (ip->protocol == IP_PROTOCOL_ICMP)
{
- if (get_icmp_i2o_ed_key (b, ip, 0, ~0ULL, 0, 0, 0, &kv))
+ if (get_icmp_i2o_ed_key (b, ip, 0, ~0, ~0, 0, 0, 0, &kv))
return 0;
}
else if (ip->protocol == IP_PROTOCOL_UDP || ip->protocol == IP_PROTOCOL_TCP)
{
make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol, 0,
vnet_buffer (b)->ip.reass.l4_src_port,
- vnet_buffer (b)->ip.reass.l4_dst_port, ~0ULL, &kv);
+ vnet_buffer (b)->ip.reass.l4_dst_port, ~0, ~0, &kv);
}
else
{
make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol, 0, 0,
- 0, ~0ULL, &kv);
+ 0, ~0, ~0, &kv);
}
if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value))
{
- s = pool_elt_at_index (tsm->sessions, value.value);
+ ASSERT (thread_index == ed_value_get_thread_index (&value));
+ s =
+ pool_elt_at_index (tsm->sessions,
+ ed_value_get_session_index (&value));
if (is_fwd_bypass_session (s))
{
if (ip->protocol == IP_PROTOCOL_TCP)
/* src NAT check */
make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol,
- tx_fib_index, src_port, dst_port, ~0ULL, &kv);
- if (!clib_bihash_search_16_8 (&tsm->out2in_ed, &kv, &value))
+ tx_fib_index, src_port, dst_port, ~0, ~0, &kv);
+ if (!clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
{
- s = pool_elt_at_index (tsm->sessions, value.value);
+ ASSERT (thread_index == ed_value_get_thread_index (&value));
+ s =
+ pool_elt_at_index (tsm->sessions,
+ ed_value_get_session_index (&value));
if (nat44_is_ses_closed (s))
{
nat_free_session_data (sm, s, thread_index, 0);
/* dst NAT check */
make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol,
- rx_fib_index, dst_port, src_port, ~0ULL, &kv);
+ rx_fib_index, dst_port, src_port, ~0, ~0, &kv);
if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value))
{
- s = pool_elt_at_index (tsm->sessions, value.value);
+ ASSERT (thread_index == ed_value_get_thread_index (&value));
+ s =
+ pool_elt_at_index (tsm->sessions,
+ ed_value_get_session_index (&value));
if (is_fwd_bypass_session (s))
return 0;
rx_fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index);
err =
- get_icmp_i2o_ed_key (b, ip, rx_fib_index, ~0ULL, p_proto, &l_port,
+ get_icmp_i2o_ed_key (b, ip, rx_fib_index, ~0, ~0, p_proto, &l_port,
&r_port, &kv);
if (err != 0)
{
goto out;
}
- s = pool_elt_at_index (tsm->sessions, value.value);
+ ASSERT (thread_index == ed_value_get_thread_index (&value));
+ s =
+ pool_elt_at_index (tsm->sessions,
+ ed_value_get_session_index (&value));
}
out:
if (s)
old_addr = ip->src_address.as_u32;
make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol,
- rx_fib_index, 0, 0, ~0ULL, &s_kv);
+ rx_fib_index, 0, 0, ~0, ~0, &s_kv);
if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &s_kv, &s_value))
{
- s = pool_elt_at_index (tsm->sessions, s_value.value);
+ ASSERT (thread_index == ed_value_get_thread_index (&s_value));
+ s =
+ pool_elt_at_index (tsm->sessions,
+ ed_value_get_session_index (&s_value));
new_addr = ip->src_address.as_u32 = s->out2in.addr.as_u32;
}
else
new_addr = ip->src_address.as_u32 = s->out2in.addr.as_u32;
make_ed_kv (&s->out2in.addr, &ip->dst_address, ip->protocol,
- outside_fib_index, 0, 0, ~0ULL, &s_kv);
- if (clib_bihash_search_16_8 (&tsm->out2in_ed, &s_kv, &s_value))
+ outside_fib_index, 0, 0, ~0, ~0, &s_kv);
+ if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
goto create_ses;
break;
for (i = 0; i < vec_len (sm->addresses); i++)
{
make_ed_kv (&sm->addresses[i].addr, &ip->dst_address,
- ip->protocol, outside_fib_index, 0, 0, ~0ULL,
+ ip->protocol, outside_fib_index, 0, 0, ~0, ~0,
&s_kv);
- if (clib_bihash_search_16_8 (&tsm->out2in_ed, &s_kv, &s_value))
+ if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
{
new_addr = ip->src_address.as_u32 =
sm->addresses[i].addr.as_u32;
/* Add to lookup tables */
make_ed_kv (&s->in2out.addr, &ip->dst_address, ip->protocol,
- rx_fib_index, 0, 0, s - tsm->sessions, &s_kv);
+ rx_fib_index, 0, 0, thread_index, s - tsm->sessions, &s_kv);
if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &s_kv, 1))
nat_elog_notice ("in2out key add failed");
make_ed_kv (&s->out2in.addr, &ip->dst_address, ip->protocol,
- outside_fib_index, 0, 0, s - tsm->sessions, &s_kv);
- if (clib_bihash_add_del_16_8 (&tsm->out2in_ed, &s_kv, 1))
+ outside_fib_index, 0, 0, thread_index, s - tsm->sessions,
+ &s_kv);
+ if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &s_kv, 1))
nat_elog_notice ("out2in key add failed");
}
make_ed_kv (&ip0->src_address, &ip0->dst_address,
ip0->protocol, rx_fib_index0,
vnet_buffer (b0)->ip.reass.l4_src_port,
- vnet_buffer (b0)->ip.reass.l4_dst_port, ~0ULL, &kv0);
+ vnet_buffer (b0)->ip.reass.l4_dst_port, ~0, ~0, &kv0);
// lookup for session
if (clib_bihash_search_16_8 (&tsm->in2out_ed, &kv0, &value0))
next0 = def_slow;
goto trace0;
}
- s0 = pool_elt_at_index (tsm->sessions, value0.value);
+ ASSERT (thread_index == ed_value_get_thread_index (&value0));
+ s0 =
+ pool_elt_at_index (tsm->sessions,
+ ed_value_get_session_index (&value0));
if (s0->tcp_closed_timestamp)
{
make_ed_kv (&ip0->src_address, &ip0->dst_address,
ip0->protocol, rx_fib_index0,
vnet_buffer (b0)->ip.reass.l4_src_port,
- vnet_buffer (b0)->ip.reass.l4_dst_port, ~0ULL, &kv0);
+ vnet_buffer (b0)->ip.reass.l4_dst_port, ~0, ~0, &kv0);
if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv0, &value0))
{
- s0 = pool_elt_at_index (tsm->sessions, value0.value);
+ ASSERT (thread_index == ed_value_get_thread_index (&value0));
+ s0 =
+ pool_elt_at_index (tsm->sessions,
+ ed_value_get_session_index (&value0));
if (s0->tcp_closed_timestamp && now >= s0->tcp_closed_timestamp)
{
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
{
l_addr = &s->in2out.addr;
r_addr = &s->ext_host_addr;
proto = nat_proto_to_ip_proto (s->in2out.protocol);
- make_ed_kv (l_addr, r_addr, proto, fib_index, l_port, r_port, ~0ULL,
- &ed_kv);
+ 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");
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");
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
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)))
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 *
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;
}
make_ed_kv (&ip->src_address, &ip->dst_address,
ip->protocol, fib_index, udp->src_port, udp->dst_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 += 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;
- }
- }
- /* *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) +
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 == 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;
+ }
}
}
make_ed_kv (in_addr, &s->ext_host_nat_addr,
nat_proto_to_ip_proto (proto), fib_index, in_port,
- s->ext_host_nat_port, s - tsm->sessions, &kv);
+ 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, nat_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))
+ 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;
}
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
{
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;
+ // clear per thread session counters
+ 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)
{
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
{
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;
clib_bihash_8_8_t in2out;
/* Endpoint dependent sessions lookup tables */
- clib_bihash_16_8_t out2in_ed;
clib_bihash_16_8_t in2out_ed;
/* Find-a-user => src address lookup */
/* Static mapping pool */
snat_static_mapping_t *static_mappings;
+ /* Endpoint-dependent out2in mappings */
+ clib_bihash_16_8_t out2in_ed;
+
/* Interface pool */
snat_interface_t *interfaces;
snat_interface_t *output_feature_interfaces;
*/
void nat44_db_free (snat_main_per_thread_data_t * tsm);
+void nat44_sessions_clear ();
+
/**
* @brief Find or create NAT user
*
return s;
}
-static_always_inline void
-nat44_sessions_clear ()
-{
- snat_main_t *sm = &snat_main;
- snat_main_per_thread_data_t *tsm;
-
- /* *INDENT-OFF* */
- vec_foreach (tsm, sm->per_thread_data)
- {
- u32 ti;
-
- nat44_db_free (tsm);
- nat44_db_init (tsm);
-
- ti = tsm->snat_thread_index;
- // clear per thread session counters
- vlib_set_simple_counter (&sm->total_users, ti, 0, 0);
- vlib_set_simple_counter (&sm->total_sessions, ti, 0, 0);
- }
- /* *INDENT-ON* */
-}
-
static_always_inline void
nat44_user_del_sessions (snat_user_t * u, u32 thread_index)
{
make_ed_kv (&ip0->src_address, &ip0->dst_address,
ip0->protocol, rx_fib_index0,
vnet_buffer (b0)->ip.reass.l4_src_port,
- vnet_buffer (b0)->ip.reass.l4_dst_port, ~0ULL,
+ vnet_buffer (b0)->ip.reass.l4_dst_port, ~0, ~0,
&ed_kv0);
/* process whole packet */
if (!clib_bihash_search_16_8
vlib_cli_output (vm, "%U",
format_bihash_8_8, &sm->static_mapping_by_external,
verbose);
+ vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->out2in_ed, verbose);
vec_foreach_index (i, sm->per_thread_data)
{
tsm = vec_elt_at_index (sm->per_thread_data, i);
{
vlib_cli_output (vm, "%U", format_bihash_16_8, &tsm->in2out_ed,
verbose);
- vlib_cli_output (vm, "%U", format_bihash_16_8, &tsm->out2in_ed,
- verbose);
}
else
{
clib_bihash_kv_16_8_t ed_kv, ed_value;
make_ed_kv (&ip0->dst_address, &ip0->src_address,
ip0->protocol, sm->outside_fib_index, udp0->dst_port,
- udp0->src_port, ~0ULL, &ed_kv);
- rv = clib_bihash_search_16_8 (&sm->per_thread_data[ti].out2in_ed,
- &ed_kv, &ed_value);
- si = ed_value.value;
+ udp0->src_port, ~0, ~0, &ed_kv);
+ rv = clib_bihash_search_16_8 (&sm->out2in_ed, &ed_kv, &ed_value);
+ ASSERT (ti == ed_value_get_thread_index (&ed_value));
+ si = ed_value_get_session_index (&ed_value);
}
else
{
clib_bihash_kv_16_8_t ed_kv, ed_value;
make_ed_kv (&ip0->dst_address, &ip0->src_address,
inner_ip0->protocol, sm->outside_fib_index,
- l4_header->src_port, l4_header->dst_port, ~0ULL,
+ l4_header->src_port, l4_header->dst_port, ~0, ~0,
&ed_kv);
- if (clib_bihash_search_16_8
- (&sm->per_thread_data[ti].out2in_ed, &ed_kv, &ed_value))
+ if (clib_bihash_search_16_8 (&sm->out2in_ed, &ed_kv, &ed_value))
return 1;
- si = ed_value.value;
+ ASSERT (ti == ed_value_get_thread_index (&ed_value));
+ si = ed_value_get_session_index (&ed_value);
}
else
{
snat_static_mapping_t *m;
ip_csum_t sum;
snat_session_t *s;
- snat_main_per_thread_data_t *tsm;
if (sm->num_workers > 1)
ti = sm->worker_out2in_cb (b, ip, sm->outside_fib_index, 0);
else
ti = sm->num_workers;
- tsm = &sm->per_thread_data[ti];
old_addr = ip->dst_address.as_u32;
make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol,
- sm->outside_fib_index, 0, 0, ~0ULL, &s_kv);
- if (clib_bihash_search_16_8 (&tsm->out2in_ed, &s_kv, &s_value))
+ sm->outside_fib_index, 0, 0, ~0, ~0, &s_kv);
+ if (clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
{
make_sm_kv (&kv, &ip->dst_address, 0, 0, 0);
if (clib_bihash_search_8_8
}
else
{
- s = pool_elt_at_index (sm->per_thread_data[ti].sessions, s_value.value);
+ ASSERT (ti == ed_value_get_thread_index (&s_value));
+ s =
+ pool_elt_at_index (sm->per_thread_data[ti].sessions,
+ ed_value_get_session_index (&s_value));
if (vnet_buffer (b)->sw_if_index[VLIB_TX] == ~0)
vnet_buffer (b)->sw_if_index[VLIB_TX] = s->in2out.fib_index;
new_addr = ip->dst_address.as_u32 = s->in2out.addr.as_u32;
always_inline void
make_ed_kv (ip4_address_t * l_addr, ip4_address_t * r_addr, u8 proto,
- u32 fib_index, u16 l_port, u16 r_port, u64 value,
- clib_bihash_kv_16_8_t * kv)
+ u32 fib_index, u16 l_port, u16 r_port, u32 thread_index,
+ u32 session_index, clib_bihash_kv_16_8_t * kv)
{
kv->key[0] = (u64) r_addr->as_u32 << 32 | l_addr->as_u32;
kv->key[1] =
(u64) r_port << 48 | (u64) l_port << 32 | fib_index << 8 | proto;
- kv->value = value;
+ kv->value = (u64) thread_index << 32 | session_index;
+}
+
+always_inline u32
+ed_value_get_thread_index (clib_bihash_kv_16_8_t * value)
+{
+ return value->value >> 32;
+}
+
+always_inline u32
+ed_value_get_session_index (clib_bihash_kv_16_8_t * value)
+{
+ return value->value & ~(u32) 0;
+}
+
+always_inline void
+split_ed_value (clib_bihash_kv_16_8_t * value, u32 * thread_index,
+ u32 * session_index)
+{
+ if (thread_index)
+ {
+ *thread_index = ed_value_get_thread_index (value);
+ }
+ if (session_index)
+ {
+ *session_index = ed_value_get_session_index (value);
+ }
}
always_inline void
static_always_inline int
get_icmp_i2o_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index,
- u64 value, u8 * nat_proto, u16 * l_port, u16 * r_port,
- clib_bihash_kv_16_8_t * kv)
+ u32 thread_index, u32 session_index, u8 * nat_proto,
+ u16 * l_port, u16 * r_port, clib_bihash_kv_16_8_t * kv)
{
u8 proto;
u16 _l_port, _r_port;
return NAT_IN2OUT_ED_ERROR_UNSUPPORTED_PROTOCOL;
}
}
- make_ed_kv (l_addr, r_addr, proto, rx_fib_index, _l_port, _r_port, value,
- kv);
+ make_ed_kv (l_addr, r_addr, proto, rx_fib_index, _l_port, _r_port,
+ thread_index, session_index, kv);
if (nat_proto)
{
*nat_proto = ip_proto_to_nat_proto (proto);
static_always_inline int
get_icmp_o2i_ed_key (vlib_buffer_t * b, ip4_header_t * ip0, u32 rx_fib_index,
- u64 value, u8 * nat_proto, u16 * l_port, u16 * r_port,
- clib_bihash_kv_16_8_t * kv)
+ u32 thread_index, u32 session_index, u8 * nat_proto,
+ u16 * l_port, u16 * r_port, clib_bihash_kv_16_8_t * kv)
{
icmp46_header_t *icmp0;
u8 proto;
return -1;
}
}
- make_ed_kv (l_addr, r_addr, proto, rx_fib_index, _l_port, _r_port, value,
- kv);
+ make_ed_kv (l_addr, r_addr, proto, rx_fib_index, _l_port, _r_port,
+ thread_index, session_index, kv);
if (nat_proto)
{
*nat_proto = ip_proto_to_nat_proto (proto);
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");
/* Add to lookup tables */
make_ed_kv (&e_key.addr, &s->ext_host_addr, ip->protocol,
- e_key.fib_index, e_key.port, s->ext_host_port,
+ e_key.fib_index, e_key.port, s->ext_host_port, thread_index,
s - tsm->sessions, &kv);
ctx.now = now;
ctx.thread_index = thread_index;
- if (clib_bihash_add_or_overwrite_stale_16_8 (&tsm->out2in_ed, &kv,
+ if (clib_bihash_add_or_overwrite_stale_16_8 (&sm->out2in_ed, &kv,
nat44_o2i_ed_is_idle_session_cb,
&ctx))
nat_elog_notice ("out2in-ed key add failed");
{
b->error = node->errors[NAT_OUT2IN_ED_ERROR_OUT_OF_PORTS];
nat_ed_session_delete (sm, s, thread_index, 1);
- if (clib_bihash_add_del_16_8 (&tsm->out2in_ed, &kv, 0))
+ if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &kv, 0))
nat_elog_notice ("out2in-ed key del failed");
return 0;
}
s->flags |= SNAT_SESSION_FLAG_TWICE_NAT;
make_ed_kv (&l_key.addr, &s->ext_host_nat_addr, ip->protocol,
l_key.fib_index, l_key.port, s->ext_host_nat_port,
- s - tsm->sessions, &kv);
+ thread_index, s - tsm->sessions, &kv);
}
else
{
make_ed_kv (&l_key.addr, &s->ext_host_addr, ip->protocol,
- l_key.fib_index, l_key.port, s->ext_host_port,
+ l_key.fib_index, l_key.port, s->ext_host_port, thread_index,
s - tsm->sessions, &kv);
}
if (clib_bihash_add_or_overwrite_stale_16_8 (&tsm->in2out_ed, &kv,
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
make_ed_kv (&ip->src_address, &ip->dst_address, ip->protocol,
- rx_fib_index, src_port, dst_port, ~0ULL, &kv);
+ rx_fib_index, src_port, dst_port, ~0, ~0, &kv);
if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value))
return 1;
if (ip->protocol == IP_PROTOCOL_ICMP)
{
if (get_icmp_o2i_ed_key
- (b, ip, rx_fib_index, ~0ULL, 0, &l_port, &r_port, &kv))
+ (b, ip, rx_fib_index, ~0, ~0, 0, &l_port, &r_port, &kv))
return;
}
else
r_port = 0;
}
make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol,
- rx_fib_index, l_port, r_port, ~0ULL, &kv);
+ rx_fib_index, l_port, r_port, ~0, ~0, &kv);
}
if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv, &value))
{
- s = pool_elt_at_index (tsm->sessions, value.value);
+ ASSERT (thread_index == ed_value_get_thread_index (&value));
+ s =
+ pool_elt_at_index (tsm->sessions,
+ ed_value_get_session_index (&value));
}
else
{
rx_fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index);
if (get_icmp_o2i_ed_key
- (b, ip, rx_fib_index, ~0ULL, p_proto, &l_port, &r_port, &kv))
+ (b, ip, rx_fib_index, ~0, ~0, p_proto, &l_port, &r_port, &kv))
{
b->error = node->errors[NAT_OUT2IN_ED_ERROR_UNSUPPORTED_PROTOCOL];
next = NAT_NEXT_DROP;
goto out;
}
- if (clib_bihash_search_16_8 (&tsm->out2in_ed, &kv, &value))
+ if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv, &value))
{
/* Try to match static mapping */
e_key.addr = ip->dst_address;
goto out;
}
- s = pool_elt_at_index (tsm->sessions, value.value);
+ ASSERT (thread_index == ed_value_get_thread_index (&value));
+ s =
+ pool_elt_at_index (tsm->sessions,
+ ed_value_get_session_index (&value));
}
out:
if (s)
old_addr = ip->dst_address.as_u32;
make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol, rx_fib_index,
- 0, 0, ~0ULL, &s_kv);
+ 0, 0, ~0, ~0, &s_kv);
- if (!clib_bihash_search_16_8 (&tsm->out2in_ed, &s_kv, &s_value))
+ if (!clib_bihash_search_16_8 (&sm->out2in_ed, &s_kv, &s_value))
{
- s = pool_elt_at_index (tsm->sessions, s_value.value);
+ ASSERT (thread_index == ed_value_get_thread_index (&s_value));
+ s =
+ pool_elt_at_index (tsm->sessions,
+ ed_value_get_session_index (&s_value));
new_addr = ip->dst_address.as_u32 = s->in2out.addr.as_u32;
}
else
/* Add to lookup tables */
s_kv.value = s - tsm->sessions;
- if (clib_bihash_add_del_16_8 (&tsm->out2in_ed, &s_kv, 1))
+ if (clib_bihash_add_del_16_8 (&sm->out2in_ed, &s_kv, 1))
nat_elog_notice ("out2in key add failed");
make_ed_kv (&ip->dst_address, &ip->src_address, ip->protocol,
- m->fib_index, 0, 0, s - tsm->sessions, &s_kv);
+ m->fib_index, 0, 0, thread_index, s - tsm->sessions, &s_kv);
if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &s_kv, 1))
nat_elog_notice ("in2out key add failed");
}
static inline uword
nat44_ed_out2in_fast_path_node_fn_inline (vlib_main_t * vm,
vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+ vlib_frame_t * frame,
+ int is_multi_worker)
{
u32 n_left_from, *from, *to_next, pkts_processed = 0, stats_node_index;
nat_next_t next_index;
make_ed_kv (&ip0->dst_address, &ip0->src_address,
ip0->protocol, rx_fib_index0,
vnet_buffer (b0)->ip.reass.l4_dst_port,
- vnet_buffer (b0)->ip.reass.l4_src_port, ~0ULL, &kv0);
+ vnet_buffer (b0)->ip.reass.l4_src_port, ~0, ~0, &kv0);
+
+ /* there is a stashed index in vnet_buffer2 from handoff node,
+ * see if we can use it */
+ if (is_multi_worker && PREDICT_TRUE
+ (!pool_is_free_index
+ (tsm->sessions,
+ vnet_buffer2 (b0)->nat.ed_out2in_nat_session_index)))
+ {
+ s0 = pool_elt_at_index (tsm->sessions,
+ vnet_buffer2 (b0)->
+ nat.ed_out2in_nat_session_index);
+ if (PREDICT_TRUE
+ (s0->out2in.addr.as_u32 == ip0->dst_address.as_u32
+ && s0->out2in.port ==
+ vnet_buffer (b0)->ip.reass.l4_dst_port
+ && s0->out2in.protocol ==
+ ip_proto_to_nat_proto (ip0->protocol)
+ && s0->out2in.fib_index == rx_fib_index0
+ && s0->ext_host_addr.as_u32 == ip0->src_address.as_u32
+ && s0->ext_host_port ==
+ vnet_buffer (b0)->ip.reass.l4_src_port))
+ {
+ /* yes, this is the droid we're looking for */
+ goto skip_lookup;
+ }
+ }
- if (clib_bihash_search_16_8 (&tsm->out2in_ed, &kv0, &value0))
+ if (clib_bihash_search_16_8 (&sm->out2in_ed, &kv0, &value0))
{
next0 = NAT_NEXT_OUT2IN_ED_SLOW_PATH;
goto trace0;
}
- s0 = pool_elt_at_index (tsm->sessions, value0.value);
+ ASSERT (thread_index == ed_value_get_thread_index (&value0));
+ s0 =
+ pool_elt_at_index (tsm->sessions,
+ ed_value_get_session_index (&value0));
+ skip_lookup:
if (s0->tcp_closed_timestamp)
{
if (now >= s0->tcp_closed_timestamp)
make_ed_kv (&ip0->dst_address, &ip0->src_address,
ip0->protocol, rx_fib_index0,
vnet_buffer (b0)->ip.reass.l4_dst_port,
- vnet_buffer (b0)->ip.reass.l4_src_port, ~0ULL, &kv0);
+ vnet_buffer (b0)->ip.reass.l4_src_port, ~0, ~0, &kv0);
s0 = NULL;
- if (!clib_bihash_search_16_8 (&tsm->out2in_ed, &kv0, &value0))
+ if (!clib_bihash_search_16_8 (&sm->out2in_ed, &kv0, &value0))
{
- s0 = pool_elt_at_index (tsm->sessions, value0.value);
+ ASSERT (thread_index == ed_value_get_thread_index (&value0));
+ s0 =
+ pool_elt_at_index (tsm->sessions,
+ ed_value_get_session_index (&value0));
if (s0->tcp_closed_timestamp && now >= s0->tcp_closed_timestamp)
{
vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
- return nat44_ed_out2in_fast_path_node_fn_inline (vm, node, frame);
+ if (snat_main.num_workers > 1)
+ {
+ return nat44_ed_out2in_fast_path_node_fn_inline (vm, node, frame, 1);
+ }
+ else
+ {
+ return nat44_ed_out2in_fast_path_node_fn_inline (vm, node, frame, 0);
+ }
}
/* *INDENT-OFF* */
struct
{
u32 arc_next;
- u32 unused;
+ u32 ed_out2in_nat_session_index;
} nat;
union