};
nat44_is_idle_session_ctx_t ctx;
- nat44_session_try_cleanup (&key->l_addr, rx_fib_index, thread_index, now);
+ u32 cleared = 0;
if (PREDICT_FALSE (nat44_maximum_sessions_exceeded (sm, thread_index)))
{
- b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_SESSIONS_EXCEEDED];
- nat_ipfix_logging_max_sessions (thread_index, sm->max_translations);
- nat_elog_notice ("maximum sessions exceeded");
- return NAT_NEXT_DROP;
+ if (PREDICT_FALSE
+ (!(cleared = nat44_users_cleanup (thread_index, now))))
+ {
+ b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_SESSIONS_EXCEEDED];
+ nat_ipfix_logging_max_sessions (thread_index, sm->max_translations);
+ nat_elog_notice ("maximum sessions exceeded");
+ return NAT_NEXT_DROP;
+ }
}
key0.addr = key->l_addr;
key1.protocol = key0.protocol = proto;
key0.fib_index = rx_fib_index;
key1.fib_index = sm->outside_fib_index;
+
/* First try to match static mapping by local address and port */
if (snat_static_mapping_match
(sm, key0, &key1, 0, 0, 0, &lb, 0, &identity_nat))
sm->port_per_thread,
tsm->snat_thread_index))
{
- nat_elog_notice ("addresses exhausted");
- b->error = node->errors[NAT_IN2OUT_ED_ERROR_OUT_OF_PORTS];
- return NAT_NEXT_DROP;
+ if (cleared || !nat44_out_of_ports_cleanup (thread_index, now) ||
+ snat_alloc_outside_address_and_port (sm->addresses,
+ rx_fib_index, thread_index,
+ &key1, sm->port_per_thread,
+ tsm->snat_thread_index))
+ {
+ nat_elog_notice ("addresses exhausted");
+ b->error = node->errors[NAT_IN2OUT_ED_ERROR_OUT_OF_PORTS];
+ return NAT_NEXT_DROP;
+ }
}
}
else
*sessionp = s;
return next;
}
-
is_sm = 1;
}
- if (proto == SNAT_PROTOCOL_TCP)
+ if (PREDICT_TRUE (proto == SNAT_PROTOCOL_TCP))
{
- if (!tcp_flags_is_init
- (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
+ if (PREDICT_FALSE
+ (!tcp_flags_is_init
+ (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags)))
{
b->error = node->errors[NAT_IN2OUT_ED_ERROR_NON_SYN];
+ if (!is_sm)
+ snat_free_outside_address_and_port (sm->addresses,
+ thread_index, &key1);
return NAT_NEXT_DROP;
}
}
if (!is_sm)
snat_free_outside_address_and_port (sm->addresses,
thread_index, &key1);
+ b->error = node->errors[NAT_IN2OUT_ED_ERROR_CANNOT_CREATE_USER];
return NAT_NEXT_DROP;
}
if (!is_sm)
snat_free_outside_address_and_port (sm->addresses,
thread_index, &key1);
+ b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_USER_SESS_EXCEEDED];
return NAT_NEXT_DROP;
}
thread_index);
if (!u)
{
+ b->error = node->errors[NAT_IN2OUT_ED_ERROR_CANNOT_CREATE_USER];
nat_elog_warn ("create NAT user failed");
return 0;
}
s = nat_ed_session_alloc (sm, u, thread_index, now);
if (!s)
{
+ b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_USER_SESS_EXCEEDED];
nat44_delete_user_with_no_session (sm, u, thread_index);
nat_elog_warn ("create NAT session failed");
return 0;
next0 = def_slow;
goto trace0;
}
-
s0 = pool_elt_at_index (tsm->sessions, value0.value);
+ // drop if session expired
+ u64 sess_timeout_time;
+ sess_timeout_time = s0->last_heard +
+ (f64) nat44_session_get_timeout (sm, s0);
+ if (now >= sess_timeout_time)
+ {
+ // delete session
+ nat_free_session_data (sm, s0, thread_index, 0);
+ nat44_delete_session (sm, s0, thread_index);
+
+ b0->error = node->errors[NAT_IN2OUT_ED_ERROR_SESS_EXPIRED];
+ next0 = NAT_NEXT_DROP;
+ goto trace0;
+ }
+ //
+
b0->flags |= VNET_BUFFER_F_IS_NATED;
if (!is_output_feature)