{
if (ip->protocol == IP_PROTOCOL_TCP)
{
- if (nat44_set_tcp_session_state_i2o (sm, s, b, thread_index))
+ if (nat44_set_tcp_session_state_i2o
+ (sm, now, s, b, thread_index))
return 1;
}
/* Accounting */
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
u32 tcp_packets = 0, udp_packets = 0, icmp_packets = 0, other_packets =
0, def_slow;
+ u32 tcp_closed_drops = 0;
def_slow = is_output_feature ? NAT_NEXT_IN2OUT_ED_OUTPUT_SLOW_PATH :
NAT_NEXT_IN2OUT_ED_SLOW_PATH;
}
s0 = pool_elt_at_index (tsm->sessions, value0.value);
+ if (s0->tcp_close_timestamp)
+ {
+ if (now >= s0->tcp_close_timestamp)
+ {
+ // session is closed, go slow path
+ next0 = def_slow;
+ }
+ else
+ {
+ // session in transitory timeout, drop
+ ++tcp_closed_drops;
+ b0->error = node->errors[NAT_IN2OUT_ED_ERROR_TCP_CLOSED];
+ next0 = NAT_NEXT_DROP;
+ }
+ goto trace0;
+ }
+
// drop if session expired
u64 sess_timeout_time;
sess_timeout_time = s0->last_heard +
next0 = NAT_NEXT_DROP;
goto trace0;
}
- //
b0->flags |= VNET_BUFFER_F_IS_NATED;
tcp0->checksum = ip_csum_fold (sum0);
}
tcp_packets++;
- if (nat44_set_tcp_session_state_i2o (sm, s0, b0, thread_index))
+ if (nat44_set_tcp_session_state_i2o
+ (sm, now, s0, b0, thread_index))
goto trace0;
}
else if (!vnet_buffer (b0)->ip.reass.is_non_first_fragment
vnet_buffer (b0)->ip.reass.l4_src_port,
vnet_buffer (b0)->ip.reass.l4_dst_port);
- if (clib_bihash_search_16_8 (&tsm->in2out_ed, &kv0, &value0))
+ if (!clib_bihash_search_16_8 (&tsm->in2out_ed, &kv0, &value0))
{
+ s0 = pool_elt_at_index (tsm->sessions, value0.value);
+ if (s0->tcp_close_timestamp && now >= s0->tcp_close_timestamp)
+ {
+ nat_free_session_data (sm, s0, thread_index, 0);
+ nat44_delete_session (sm, s0, thread_index);
+ s0 = NULL;
+ }
+ }
+
+ if (!s0)
+ {
if (is_output_feature)
{
if (PREDICT_FALSE
goto trace0;
}
- else
- {
- s0 = pool_elt_at_index (tsm->sessions, value0.value);
- }
-
b0->flags |= VNET_BUFFER_F_IS_NATED;
tcp0->checksum = ip_csum_fold (sum0);
}
tcp_packets++;
- if (nat44_set_tcp_session_state_i2o (sm, s0, b0, thread_index))
+ if (nat44_set_tcp_session_state_i2o
+ (sm, now, s0, b0, thread_index))
goto trace0;
}
else if (!vnet_buffer (b0)->ip.reass.is_non_first_fragment