if (!(seq_leq (tc->snd_una, vnet_buffer (b)->tcp.ack_number)
&& seq_leq (vnet_buffer (b)->tcp.ack_number, tc->snd_nxt)))
{
- if (seq_leq (vnet_buffer (b)->tcp.ack_number, tc->snd_nxt)
- && seq_gt (vnet_buffer (b)->tcp.ack_number, tc->snd_una))
- {
- tc->snd_nxt = vnet_buffer (b)->tcp.ack_number;
- goto acceptable;
- }
*error = TCP_ERROR_ACK_INVALID;
return -1;
}
-acceptable:
tc->bytes_acked = vnet_buffer (b)->tcp.ack_number - tc->snd_una;
tc->snd_una = vnet_buffer (b)->tcp.ack_number;
*error = TCP_ERROR_ACK_OK;
/* If the ACK acks something not yet sent (SEG.ACK > SND.NXT) */
if (PREDICT_FALSE (seq_gt (vnet_buffer (b)->tcp.ack_number, tc->snd_nxt)))
{
- /* We've probably entered recovery and the peer still has some
- * of the data we've sent. Update snd_nxt and accept the ack */
- if (seq_leq (vnet_buffer (b)->tcp.ack_number, tc->snd_nxt)
- && seq_gt (vnet_buffer (b)->tcp.ack_number, tc->snd_una))
- {
- tc->snd_nxt = vnet_buffer (b)->tcp.ack_number;
- goto process_ack;
- }
-
tc->errors.above_ack_wnd += 1;
*error = TCP_ERROR_ACK_FUTURE;
TCP_EVT (TCP_EVT_ACK_RCV_ERR, tc, 0, vnet_buffer (b)->tcp.ack_number);
return 0;
}
-process_ack:
-
/*
* Looks okay, process feedback
*/
return tcp46_established_inline (vm, node, from_frame, 0 /* is_ip4 */ );
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp4_established_node) = {
.name = "tcp4-established",
/* Takes a vector of packets. */
.error_counters = tcp_input_error_counters,
.format_trace = format_tcp_rx_trace_short,
};
-/* *INDENT-ON* */
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp6_established_node) = {
.name = "tcp6-established",
/* Takes a vector of packets. */
.error_counters = tcp_input_error_counters,
.format_trace = format_tcp_rx_trace_short,
};
-/* *INDENT-ON* */
static u8
SESSION_E_NONE))
{
tcp_send_reset_w_pkt (new_tc, b[0], thread_index, is_ip4);
- tcp_connection_cleanup (new_tc);
+ tcp_program_cleanup (wrk, new_tc);
+ new_tc->state = TCP_STATE_CLOSED;
+ new_tc->c_s_index = ~0;
error = TCP_ERROR_CREATE_SESSION_FAIL;
goto cleanup_ho;
}
if (session_stream_connect_notify (&new_tc->connection,
SESSION_E_NONE))
{
- tcp_connection_cleanup (new_tc);
tcp_send_reset_w_pkt (tc, b[0], thread_index, is_ip4);
+ tcp_program_cleanup (wrk, new_tc);
+ new_tc->state = TCP_STATE_CLOSED;
+ new_tc->c_s_index = ~0;
TCP_EVT (TCP_EVT_RST_SENT, tc);
error = TCP_ERROR_CREATE_SESSION_FAIL;
goto cleanup_ho;
return tcp46_syn_sent_inline (vm, node, from_frame, 0 /* is_ip4 */ );
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp4_syn_sent_node) =
{
.name = "tcp4-syn-sent",
.error_counters = tcp_input_error_counters,
.format_trace = format_tcp_rx_trace_short,
};
-/* *INDENT-ON* */
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp6_syn_sent_node) =
{
.name = "tcp6-syn-sent",
.error_counters = tcp_input_error_counters,
.format_trace = format_tcp_rx_trace_short,
};
-/* *INDENT-ON* */
static void
tcp46_rcv_process_trace_frame (vlib_main_t *vm, vlib_node_runtime_t *node,
switch (tc->state)
{
case TCP_STATE_SYN_RCVD:
-
- /* Make sure the segment is exactly right */
- if (tc->rcv_nxt != vnet_buffer (b[0])->tcp.seq_number)
- {
- tcp_send_reset_w_pkt (tc, b[0], thread_index, is_ip4);
- error = TCP_ERROR_SEGMENT_INVALID;
- goto drop;
- }
-
/*
* If the segment acknowledgment is not acceptable, form a
* reset segment,
tcp_connection_cleanup (tc);
goto drop;
}
- error = TCP_ERROR_ACK_OK;
+ error = TCP_ERROR_CONN_ACCEPTED;
break;
case TCP_STATE_ESTABLISHED:
/* We can get packets in established state here because they
if (max_deq > tc->burst_acked)
break;
- tcp_send_fin (tc);
tcp_connection_timers_reset (tc);
+ tcp_send_fin (tc);
tcp_connection_set_state (tc, TCP_STATE_LAST_ACK);
tcp_timer_set (&wrk->timer_wheel, tc, TCP_TIMER_WAITCLOSE,
tcp_cfg.lastack_time);
return tcp46_rcv_process_inline (vm, node, from_frame, 0 /* is_ip4 */ );
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp4_rcv_process_node) = {
.name = "tcp4-rcv-process",
/* Takes a vector of packets. */
.error_counters = tcp_input_error_counters,
.format_trace = format_tcp_rx_trace_short,
};
-/* *INDENT-ON* */
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp6_rcv_process_node) = {
.name = "tcp6-rcv-process",
/* Takes a vector of packets. */
.error_counters = tcp_input_error_counters,
.format_trace = format_tcp_rx_trace_short,
};
-/* *INDENT-ON* */
static void
tcp46_listen_trace_frame (vlib_main_t *vm, vlib_node_runtime_t *node,
return tcp46_listen_inline (vm, node, from_frame, 0 /* is_ip4 */ );
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp4_listen_node) = {
.name = "tcp4-listen",
/* Takes a vector of packets. */
.error_counters = tcp_input_error_counters,
.format_trace = format_tcp_rx_trace_short,
};
-/* *INDENT-ON* */
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp6_listen_node) = {
.name = "tcp6-listen",
/* Takes a vector of packets. */
.error_counters = tcp_input_error_counters,
.format_trace = format_tcp_rx_trace_short,
};
-/* *INDENT-ON* */
always_inline uword
tcp46_drop_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
1 /* is_nolookup */ );
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp4_input_nolookup_node) =
{
.name = "tcp4-input-nolookup",
.format_buffer = format_tcp_header,
.format_trace = format_tcp_rx_trace,
};
-/* *INDENT-ON* */
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp6_input_nolookup_node) =
{
.name = "tcp6-input-nolookup",
.format_buffer = format_tcp_header,
.format_trace = format_tcp_rx_trace,
};
-/* *INDENT-ON* */
VLIB_NODE_FN (tcp4_input_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_frame_t * from_frame)
0 /* is_nolookup */ );
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp4_input_node) =
{
.name = "tcp4-input",
.format_buffer = format_tcp_header,
.format_trace = format_tcp_rx_trace,
};
-/* *INDENT-ON* */
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp6_input_node) =
{
.name = "tcp6-input",
.format_buffer = format_tcp_header,
.format_trace = format_tcp_rx_trace,
};
-/* *INDENT-ON* */
#ifndef CLIB_MARCH_VARIANT
void