tcp: validate connections in output

Type: feature

This shouldn't happen unless connections are removed after buffers were
enqueued to tcp-output and before tcp-output runs. For instance, packet
is enqueued to tcp output and cleanup is called for connection.

Change-Id: Ib7dd82ffa6cfb21ff5068aba010e0a3497eeea13
Signed-off-by: Florin Coras <fcoras@cisco.com>
This commit is contained in:
Florin Coras
2019-08-30 10:00:30 -07:00
committed by John Lo
parent 5c2f96436a
commit 78dae00881
+46 -9
View File
@@ -2141,6 +2141,10 @@ tcp_output_handle_packet (tcp_connection_t * tc0, vlib_buffer_t * b0,
*next0 = tc0->next_node_index;
vnet_buffer (b0)->tcp.next_node_opaque = tc0->next_node_opaque;
}
else
{
*next0 = TCP_OUTPUT_NEXT_IP_LOOKUP;
}
vnet_buffer (b0)->sw_if_index[VLIB_TX] = tc0->c_fib_index;
vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
@@ -2199,18 +2203,44 @@ tcp46_output_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
CLIB_PREFETCH (b[3]->data, 2 * CLIB_CACHE_LINE_BYTES, STORE);
}
next[0] = next[1] = TCP_OUTPUT_NEXT_IP_LOOKUP;
tc0 = tcp_connection_get (vnet_buffer (b[0])->tcp.connection_index,
thread_index);
tc1 = tcp_connection_get (vnet_buffer (b[1])->tcp.connection_index,
thread_index);
tcp_output_push_ip (vm, b[0], tc0, is_ip4);
tcp_output_push_ip (vm, b[1], tc1, is_ip4);
if (PREDICT_TRUE (!tc0 + !tc1 == 0))
{
tcp_output_push_ip (vm, b[0], tc0, is_ip4);
tcp_output_push_ip (vm, b[1], tc1, is_ip4);
tcp_output_handle_packet (tc0, b[0], error_node, &next[0], is_ip4);
tcp_output_handle_packet (tc1, b[1], error_node, &next[1], is_ip4);
tcp_output_handle_packet (tc0, b[0], error_node, &next[0], is_ip4);
tcp_output_handle_packet (tc1, b[1], error_node, &next[1], is_ip4);
}
else
{
if (tc0 != 0)
{
tcp_output_push_ip (vm, b[0], tc0, is_ip4);
tcp_output_handle_packet (tc0, b[0], error_node, &next[0],
is_ip4);
}
else
{
b[0]->error = error_node->errors[TCP_ERROR_INVALID_CONNECTION];
next[0] = TCP_OUTPUT_NEXT_DROP;
}
if (tc1 != 0)
{
tcp_output_push_ip (vm, b[1], tc1, is_ip4);
tcp_output_handle_packet (tc1, b[1], error_node, &next[1],
is_ip4);
}
else
{
b[1]->error = error_node->errors[TCP_ERROR_INVALID_CONNECTION];
next[1] = TCP_OUTPUT_NEXT_DROP;
}
}
b += 2;
next += 2;
@@ -2226,12 +2256,19 @@ tcp46_output_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
CLIB_PREFETCH (b[1]->data, 2 * CLIB_CACHE_LINE_BYTES, STORE);
}
next[0] = TCP_OUTPUT_NEXT_IP_LOOKUP;
tc0 = tcp_connection_get (vnet_buffer (b[0])->tcp.connection_index,
thread_index);
tcp_output_push_ip (vm, b[0], tc0, is_ip4);
tcp_output_handle_packet (tc0, b[0], error_node, &next[0], is_ip4);
if (PREDICT_TRUE (tc0 != 0))
{
tcp_output_push_ip (vm, b[0], tc0, is_ip4);
tcp_output_handle_packet (tc0, b[0], error_node, &next[0], is_ip4);
}
else
{
b[0]->error = error_node->errors[TCP_ERROR_INVALID_CONNECTION];
next[0] = TCP_OUTPUT_NEXT_DROP;
}
b += 1;
next += 1;