/* Leave enough space for headers */
vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
+ vnet_buffer (b)->tcp.flags = 0;
}
/**
* Convert buffer to FIN-ACK
*/
void
-tcp_make_finack (tcp_connection_t * tc, vlib_buffer_t * b)
+tcp_make_fin (tcp_connection_t * tc, vlib_buffer_t * b)
{
tcp_main_t *tm = vnet_get_tcp_main ();
vlib_main_t *vm = tm->vlib_main;
+ u8 flags = 0;
tcp_reuse_buffer (vm, b);
- tcp_make_ack_i (tc, b, TCP_STATE_ESTABLISHED, TCP_FLAG_ACK | TCP_FLAG_FIN);
+
+ flags = TCP_FLAG_FIN | TCP_FLAG_ACK;
+ tcp_make_ack_i (tc, b, TCP_STATE_ESTABLISHED, flags);
/* Reset flags, make sure ack is sent */
- tc->flags = TCP_CONN_SNDACK;
vnet_buffer (b)->tcp.flags &= ~TCP_BUF_FLAG_DUPACK;
tc->snd_nxt += 1;
vnet_buffer (b)->tcp.flags = TCP_BUF_FLAG_ACK;
/* Init retransmit timer */
- tcp_retransmit_timer_set (tm, tc);
+ tcp_retransmit_timer_set (tc);
}
always_inline void
/* Leave enough space for headers */
vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
- tcp_make_finack (tc, b);
-
+ tcp_make_fin (tc, b);
tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
+ tc->flags |= TCP_CONN_FINSNT;
+ TCP_EVT_DBG (TCP_EVT_FIN_SENT, tc);
}
always_inline u8
vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
tc->snd_nxt += data_len;
+ TCP_EVT_DBG (TCP_EVT_PKTIZE, tc);
}
/* Send delayed ACK when timer expires */
tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
/* Re-enable retransmit timer */
- tcp_retransmit_timer_set (tm, tc);
+ tcp_retransmit_timer_set (tc);
}
else
{
vlib_node_runtime_t * node,
vlib_frame_t * from_frame, int is_ip4)
{
- tcp_main_t *tm = vnet_get_tcp_main ();
u32 n_left_from, next_index, *from, *to_next;
u32 my_thread_index = vm->cpu_index;
b0 = vlib_get_buffer (vm, bi0);
tc0 = tcp_connection_get (vnet_buffer (b0)->tcp.connection_index,
my_thread_index);
+ if (PREDICT_FALSE (tc0 == 0 || tc0->state == TCP_STATE_CLOSED))
+ {
+ error0 = TCP_ERROR_INVALID_CONNECTION;
+ next0 = TCP_OUTPUT_NEXT_DROP;
+ goto done;
+ }
+
th0 = vlib_buffer_get_current (b0);
+ TCP_EVT_DBG (TCP_EVT_OUTPUT, tc0, th0->flags, b0->current_length);
if (is_ip4)
{
if (!tcp_timer_is_active (tc0, TCP_TIMER_RETRANSMIT)
&& tc0->snd_nxt != tc0->snd_una)
{
- tcp_retransmit_timer_set (tm, tc0);
+ tcp_retransmit_timer_set (tc0);
tc0->rto_boff = 0;
}
vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
b0->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;
-
done:
- b0->error = error0 != 0 ? node->errors[error0] : 0;
+ b0->error = node->errors[error0];
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
{
return tcp46_output_inline (vm, node, from_frame, 0 /* is_ip4 */ );
}
+/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp4_output_node) =
{
.function = tcp4_output,.name = "tcp4-output",
/* Takes a vector of packets. */
- .vector_size = sizeof (u32),.n_errors = TCP_N_ERROR,.error_strings =
- tcp_error_strings,.n_next_nodes = TCP_OUTPUT_N_NEXT,.next_nodes =
- {
+ .vector_size = sizeof (u32),
+ .n_errors = TCP_N_ERROR,
+ .error_strings = tcp_error_strings,
+ .n_next_nodes = TCP_OUTPUT_N_NEXT,
+ .next_nodes = {
#define _(s,n) [TCP_OUTPUT_NEXT_##s] = n,
foreach_tcp4_output_next
#undef _
- }
-,.format_buffer = format_tcp_header,.format_trace = format_tcp_tx_trace,};
+ },
+ .format_buffer = format_tcp_header,
+ .format_trace = format_tcp_tx_trace,
+};
+/* *INDENT-ON* */
+
+VLIB_NODE_FUNCTION_MULTIARCH (tcp4_output_node, tcp4_output);
-VLIB_NODE_FUNCTION_MULTIARCH (tcp4_output_node, tcp4_output)
+/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp6_output_node) =
{
- .function = tcp6_output,.name = "tcp6-output",
+ .function = tcp6_output,
+ .name = "tcp6-output",
/* Takes a vector of packets. */
- .vector_size = sizeof (u32),.n_errors = TCP_N_ERROR,.error_strings =
- tcp_error_strings,.n_next_nodes = TCP_OUTPUT_N_NEXT,.next_nodes =
- {
+ .vector_size = sizeof (u32),
+ .n_errors = TCP_N_ERROR,
+ .error_strings = tcp_error_strings,
+ .n_next_nodes = TCP_OUTPUT_N_NEXT,
+ .next_nodes = {
#define _(s,n) [TCP_OUTPUT_NEXT_##s] = n,
foreach_tcp6_output_next
#undef _
- }
-,.format_buffer = format_tcp_header,.format_trace = format_tcp_tx_trace,};
+ },
+ .format_buffer = format_tcp_header,
+ .format_trace = format_tcp_tx_trace,
+};
+/* *INDENT-ON* */
+
+VLIB_NODE_FUNCTION_MULTIARCH (tcp6_output_node, tcp6_output);
-VLIB_NODE_FUNCTION_MULTIARCH (tcp6_output_node, tcp6_output) u32
+u32
tcp_push_header (transport_connection_t * tconn, vlib_buffer_t * b)
{
tcp_connection_t *tc;
next0 = TCP_RESET_NEXT_IP_LOOKUP;
done:
- b0->error = error0 != 0 ? node->errors[error0] : 0;
+ b0->error = node->errors[error0];
b0->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
{
};
/* *INDENT-ON* */
+VLIB_NODE_FUNCTION_MULTIARCH (tcp4_reset_node, tcp4_send_reset);
+
/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tcp6_reset_node) = {
.function = tcp6_send_reset,
};
/* *INDENT-ON* */
+VLIB_NODE_FUNCTION_MULTIARCH (tcp6_reset_node, tcp6_send_reset);
+
/*
* fd.io coding-style-patch-verification: ON
*