summaryrefslogtreecommitdiffstats
path: root/src/vnet/tcp
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2019-08-30 10:00:30 -0700
committerAndrew Yourtchenko <ayourtch@gmail.com>2019-09-29 13:15:45 +0000
commitea584d137d491789abdc4af20f5b6ad92bd21bf1 (patch)
tree950e3e5d35740b3706a91d7a7cab36dbd941665e /src/vnet/tcp
parentfe005b404585ec34a15868e84e2cea4fe780eab5 (diff)
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> (cherry picked from commit 78dae00881d26b205ee6721ce8c2bcae76996e79)
Diffstat (limited to 'src/vnet/tcp')
-rw-r--r--src/vnet/tcp/tcp_output.c55
1 files changed, 46 insertions, 9 deletions
diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c
index 239f6035d5f..d15d710eafe 100644
--- a/src/vnet/tcp/tcp_output.c
+++ b/src/vnet/tcp/tcp_output.c
@@ -2138,6 +2138,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;
@@ -2196,18 +2200,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;
@@ -2223,12 +2253,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;