From 78dae00881d26b205ee6721ce8c2bcae76996e79 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Fri, 30 Aug 2019 10:00:30 -0700 Subject: [PATCH] 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 --- src/vnet/tcp/tcp_output.c | 55 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c index 20031b2ebbd..ff281b5661d 100644 --- a/src/vnet/tcp/tcp_output.c +++ b/src/vnet/tcp/tcp_output.c @@ -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; -- 2.16.6