_(UNSUPPORTED_PROTOCOL, "Unsupported protocol") \
_(OUT2IN_PACKETS, "Good out2in packets processed") \
_(BAD_ICMP_TYPE, "unsupported ICMP type") \
-_(NO_TRANSLATION, "No translation")
+_(NO_TRANSLATION, "No translation") \
+_(MAX_SESSIONS_EXCEEDED, "Maximum sessions exceeded")
typedef enum {
#define _(sym,str) SNAT_OUT2IN_ERROR_##sym,
dlist_elt_t * per_user_list_head_elt;
ip4_header_t *ip0;
+ if (PREDICT_FALSE (maximum_sessions_exceeded(sm, thread_index)))
+ {
+ b0->error = node->errors[SNAT_OUT2IN_ERROR_MAX_SESSIONS_EXCEEDED];
+ return 0;
+ }
+
ip0 = vlib_buffer_get_current (b0);
user_key.addr = in2out.addr;
kv0.key = user_key.as_u64;
/* Ever heard of the "user" = inside ip4 address before? */
- if (clib_bihash_search_8_8 (&sm->user_hash, &kv0, &value0))
+ if (clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].user_hash,
+ &kv0, &value0))
{
/* no, make a new one */
pool_get (sm->per_thread_data[thread_index].users, u);
kv0.value = u - sm->per_thread_data[thread_index].users;
/* add user */
- clib_bihash_add_del_8_8 (&sm->user_hash, &kv0, 1 /* is_add */);
+ clib_bihash_add_del_8_8 (&sm->per_thread_data[thread_index].user_hash,
+ &kv0, 1 /* is_add */);
/* add non-traslated packets worker lookup */
kv0.value = thread_index;
/* Add to translation hashes */
kv0.key = s->in2out.as_u64;
kv0.value = s - sm->per_thread_data[thread_index].sessions;
- if (clib_bihash_add_del_8_8 (&sm->in2out, &kv0, 1 /* is_add */))
+ if (clib_bihash_add_del_8_8 (&sm->per_thread_data[thread_index].in2out, &kv0,
+ 1 /* is_add */))
clib_warning ("in2out key add failed");
kv0.key = s->out2in.as_u64;
kv0.value = s - sm->per_thread_data[thread_index].sessions;
- if (clib_bihash_add_del_8_8 (&sm->out2in, &kv0, 1 /* is_add */))
+ if (clib_bihash_add_del_8_8 (&sm->per_thread_data[thread_index].out2in, &kv0,
+ 1 /* is_add */))
clib_warning ("out2in key add failed");
/* log NAT event */
kv0.key = key0.as_u64;
- if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0))
+ if (clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].out2in, &kv0,
+ &value0))
{
/* Try to match static mapping by external address and port,
destination address and port in packet */
return next0;
}
-static void
+static snat_session_t *
snat_out2in_unknown_proto (snat_main_t *sm,
vlib_buffer_t * b,
ip4_header_t * ip,
u32 rx_fib_index,
u32 thread_index,
f64 now,
- vlib_main_t * vm)
+ vlib_main_t * vm,
+ vlib_node_runtime_t * node)
{
clib_bihash_kv_8_8_t kv, value;
clib_bihash_kv_16_8_t s_kv, s_value;
}
else
{
+ if (PREDICT_FALSE (maximum_sessions_exceeded(sm, thread_index)))
+ {
+ b->error = node->errors[SNAT_OUT2IN_ERROR_MAX_SESSIONS_EXCEEDED];
+ return 0;
+ }
+
m_key.addr = ip->dst_address;
m_key.port = 0;
m_key.protocol = 0;
m_key.fib_index = rx_fib_index;
kv.key = m_key.as_u64;
if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
- return;
+ {
+ b->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
+ return 0;
+ }
m = pool_elt_at_index (sm->static_mappings, value.value);
kv.key = u_key.as_u64;
/* Ever heard of the "user" = src ip4 address before? */
- if (clib_bihash_search_8_8 (&sm->user_hash, &kv, &value))
+ if (clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
{
/* no, make a new one */
pool_get (tsm->users, u);
kv.value = u - tsm->users;
/* add user */
- clib_bihash_add_del_8_8 (&sm->user_hash, &kv, 1);
+ clib_bihash_add_del_8_8 (&tsm->user_hash, &kv, 1);
}
else
{
clib_dlist_remove (tsm->list_pool, s->per_user_index);
clib_dlist_addtail (tsm->list_pool, s->per_user_list_head_index,
s->per_user_index);
+
+ return s;
}
-static void
+static snat_session_t *
snat_out2in_lb (snat_main_t *sm,
vlib_buffer_t * b,
ip4_header_t * ip,
u32 rx_fib_index,
u32 thread_index,
f64 now,
- vlib_main_t * vm)
+ vlib_main_t * vm,
+ vlib_node_runtime_t * node)
{
nat_ed_ses_key_t key;
clib_bihash_kv_16_8_t s_kv, s_value;
}
else
{
+ if (PREDICT_FALSE (maximum_sessions_exceeded(sm, thread_index)))
+ {
+ b->error = node->errors[SNAT_OUT2IN_ERROR_MAX_SESSIONS_EXCEEDED];
+ return 0;
+ }
+
e_key.addr = ip->dst_address;
e_key.port = udp->dst_port;
e_key.protocol = proto;
e_key.fib_index = rx_fib_index;
if (snat_static_mapping_match(sm, e_key, &l_key, 1, 0))
- return;
+ return 0;
u_key.addr = l_key.addr;
u_key.fib_index = l_key.fib_index;
kv.key = u_key.as_u64;
/* Ever heard of the "user" = src ip4 address before? */
- if (clib_bihash_search_8_8 (&sm->user_hash, &kv, &value))
+ if (clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
{
/* no, make a new one */
pool_get (tsm->users, u);
kv.value = u - tsm->users;
/* add user */
- if (clib_bihash_add_del_8_8 (&sm->user_hash, &kv, 1))
+ if (clib_bihash_add_del_8_8 (&tsm->user_hash, &kv, 1))
clib_warning ("user key add failed");
}
else
s->last_heard = now;
s->total_pkts++;
s->total_bytes += vlib_buffer_length_in_chain (vm, b);
+ return s;
}
static uword
if (PREDICT_FALSE (proto0 == ~0))
{
- snat_out2in_unknown_proto(sm, b0, ip0, rx_fib_index0,
- thread_index, now, vm);
+ s0 = snat_out2in_unknown_proto(sm, b0, ip0, rx_fib_index0,
+ thread_index, now, vm, node);
+ if (!s0)
+ next0 = SNAT_OUT2IN_NEXT_DROP;
goto trace0;
}
kv0.key = key0.as_u64;
- if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0))
+ if (clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].out2in,
+ &kv0, &value0))
{
/* Try to match static mapping by external address and port,
destination address and port in packet */
thread_index);
if (!s0)
{
- b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
next0 = SNAT_OUT2IN_NEXT_DROP;
goto trace0;
}
{
if (PREDICT_FALSE (value0.value == ~0ULL))
{
- snat_out2in_lb(sm, b0, ip0, rx_fib_index0, thread_index, now,
- vm);
+ s0 = snat_out2in_lb(sm, b0, ip0, rx_fib_index0, thread_index,
+ now, vm, node);
+ if (!s0)
+ next0 = SNAT_OUT2IN_NEXT_DROP;
goto trace0;
}
else
if (PREDICT_FALSE (proto1 == ~0))
{
- snat_out2in_unknown_proto(sm, b1, ip1, rx_fib_index1,
- thread_index, now, vm);
+ s1 = snat_out2in_unknown_proto(sm, b1, ip1, rx_fib_index1,
+ thread_index, now, vm, node);
+ if (!s1)
+ next1 = SNAT_OUT2IN_NEXT_DROP;
goto trace1;
}
kv1.key = key1.as_u64;
- if (clib_bihash_search_8_8 (&sm->out2in, &kv1, &value1))
+ if (clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].out2in,
+ &kv1, &value1))
{
/* Try to match static mapping by external address and port,
destination address and port in packet */
thread_index);
if (!s1)
{
- b1->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
next1 = SNAT_OUT2IN_NEXT_DROP;
goto trace1;
}
{
if (PREDICT_FALSE (value1.value == ~0ULL))
{
- snat_out2in_lb(sm, b1, ip1, rx_fib_index1, thread_index, now,
- vm);
+ s1 = snat_out2in_lb(sm, b1, ip1, rx_fib_index1, thread_index,
+ now, vm, node);
+ if (!s1)
+ next1 = SNAT_OUT2IN_NEXT_DROP;
goto trace1;
}
else
if (PREDICT_FALSE (proto0 == ~0))
{
- snat_out2in_unknown_proto(sm, b0, ip0, rx_fib_index0,
- thread_index, now, vm);
+ s0 = snat_out2in_unknown_proto(sm, b0, ip0, rx_fib_index0,
+ thread_index, now, vm, node);
+ if (!s0)
+ next0 = SNAT_OUT2IN_NEXT_DROP;
goto trace00;
}
kv0.key = key0.as_u64;
- if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0))
+ if (clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].out2in,
+ &kv0, &value0))
{
/* Try to match static mapping by external address and port,
destination address and port in packet */
thread_index);
if (!s0)
{
- b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ next0 = SNAT_OUT2IN_NEXT_DROP;
goto trace00;
}
}
{
if (PREDICT_FALSE (value0.value == ~0ULL))
{
- snat_out2in_lb(sm, b0, ip0, rx_fib_index0, thread_index, now,
- vm);
+ s0 = snat_out2in_lb(sm, b0, ip0, rx_fib_index0, thread_index,
+ now, vm, node);
+ if (!s0)
+ next0 = SNAT_OUT2IN_NEXT_DROP;
goto trace00;
}
else