aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2019-08-30 10:00:30 -0700
committerJohn Lo <loj@cisco.com>2019-09-10 14:11:01 +0000
commit78dae00881d26b205ee6721ce8c2bcae76996e79 (patch)
tree8bdc0b1dc07d4cae832acb1e587e9a34dbb4fc63
parent5c2f96436afd0cef13797f764474a54f464d7916 (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>
-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 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;