_(OUT_OF_PORTS, "Out of ports") \
_(BAD_OUTSIDE_FIB, "Outside VRF ID not found") \
_(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_IN2OUT_ERROR_##sym,
u32 outside_fib_index;
uword * p;
+ if (PREDICT_FALSE (maximum_sessions_exceeded(sm, thread_index)))
+ {
+ b0->error = node->errors[SNAT_IN2OUT_ERROR_MAX_SESSIONS_EXCEEDED];
+ return SNAT_IN2OUT_NEXT_DROP;
+ }
+
p = hash_get (sm->ip4_main->fib_index_by_table_id, sm->outside_vrf_id);
if (! p)
{
ip->checksum = ip_csum_fold (sum);
}
-static void
+static snat_session_t *
snat_in2out_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_IN2OUT_ERROR_MAX_SESSIONS_EXCEEDED];
+ return 0;
+ }
+
u_key.addr = ip->src_address;
u_key.fib_index = rx_fib_index;
kv.key = u_key.as_u64;
goto create_ses;
}
}
- return;
+ return 0;
}
create_ses:
if (vnet_buffer(b)->sw_if_index[VLIB_TX] == ~0)
vnet_buffer(b)->sw_if_index[VLIB_TX] = sm->outside_fib_index;
+
+ return s;
}
static snat_session_t *
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_IN2OUT_ERROR_MAX_SESSIONS_EXCEEDED];
+ return 0;
+ }
+
l_key.addr = ip->src_address;
l_key.port = udp->src_port;
l_key.protocol = proto;
{
if (PREDICT_FALSE (proto0 == ~0))
{
- snat_in2out_unknown_proto (sm, b0, ip0, rx_fib_index0,
- thread_index, now, vm);
+ s0 = snat_in2out_unknown_proto (sm, b0, ip0, rx_fib_index0,
+ thread_index, now, vm, node);
+ if (!s0)
+ next0 = SNAT_IN2OUT_NEXT_DROP;
goto trace00;
}
{
if (is_slow_path)
{
- s0 = snat_in2out_lb(sm, b0, ip0, rx_fib_index0, thread_index,
- now, vm);
+ s0 = snat_in2out_lb(sm, b0, ip0, rx_fib_index0,
+ thread_index, now, vm, node);
+ if (!s0)
+ next0 = SNAT_IN2OUT_NEXT_DROP;
goto trace00;
}
else
{
if (PREDICT_FALSE (proto1 == ~0))
{
- snat_in2out_unknown_proto (sm, b1, ip1, rx_fib_index1,
- thread_index, now, vm);
+ s1 = snat_in2out_unknown_proto (sm, b1, ip1, rx_fib_index1,
+ thread_index, now, vm, node);
+ if (!s1)
+ next1 = SNAT_IN2OUT_NEXT_DROP;
goto trace01;
}
{
if (is_slow_path)
{
- s1 = snat_in2out_lb(sm, b1, ip1, rx_fib_index1, thread_index,
- now, vm);
+ s1 = snat_in2out_lb(sm, b1, ip1, rx_fib_index1,
+ thread_index, now, vm, node);
+ if (!s1)
+ next1 = SNAT_IN2OUT_NEXT_DROP;
goto trace01;
}
else
{
if (PREDICT_FALSE (proto0 == ~0))
{
- snat_in2out_unknown_proto (sm, b0, ip0, rx_fib_index0,
- thread_index, now, vm);
+ s0 = snat_in2out_unknown_proto (sm, b0, ip0, rx_fib_index0,
+ thread_index, now, vm, node);
+ if (!s0)
+ next0 = SNAT_IN2OUT_NEXT_DROP;
goto trace0;
}
{
if (is_slow_path)
{
- s0 = snat_in2out_lb(sm, b0, ip0, rx_fib_index0, thread_index,
- now, vm);
+ s0 = snat_in2out_lb(sm, b0, ip0, rx_fib_index0,
+ thread_index, now, vm, node);
+ if (!s0)
+ next0 = SNAT_IN2OUT_NEXT_DROP;
goto trace0;
}
else