From 6c1ce53b445a9752a76659ec082430b495064b90 Mon Sep 17 00:00:00 2001 From: Srikanth Akula Date: Wed, 6 Nov 2019 18:53:13 -0800 Subject: tcp: validate the IP address while checking TCP connection Type: feature Along with the port information, we need to validate the IP address details as well. This is very useful in the case port re-use scenario Signed-off-by: Srikanth Akula Change-Id: I11e1ebcd3e56aae47ac235a89606a83c928aa6bb (cherry picked from commit cf4c2102d9dc3ccc939cca1137b24a75341f1b0c) --- src/vnet/tcp/tcp_input.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c index 8f88cb5f471..08cea1e75d0 100755 --- a/src/vnet/tcp/tcp_input.c +++ b/src/vnet/tcp/tcp_input.c @@ -2264,7 +2264,8 @@ VLIB_REGISTER_NODE (tcp6_established_node) = static u8 -tcp_lookup_is_valid (tcp_connection_t * tc, tcp_header_t * hdr) +tcp_lookup_is_valid (tcp_connection_t * tc, vlib_buffer_t * b, + tcp_header_t * hdr) { transport_connection_t *tmp = 0; u64 handle; @@ -2276,9 +2277,30 @@ tcp_lookup_is_valid (tcp_connection_t * tc, tcp_header_t * hdr) if (tc->c_lcl_port == 0 && tc->state == TCP_STATE_LISTEN) return 1; + + u8 is_ip_valid = 0; + if (tc->connection.is_ip4) + { + ip4_header_t *ip4_hdr = (ip4_header_t *) vlib_buffer_get_current (b); + is_ip_valid = + (!(ip4_address_compare + (&ip4_hdr->src_address, &tc->connection.rmt_ip.ip4) + && ip4_address_compare (&ip4_hdr->dst_address, + &tc->connection.lcl_ip.ip4))); + } + else + { + ip6_header_t *ip6_hdr = (ip6_header_t *) vlib_buffer_get_current (b); + is_ip_valid = + (!(ip6_address_compare + (&ip6_hdr->src_address, &tc->connection.rmt_ip.ip6) + && ip6_address_compare (&ip6_hdr->dst_address, + &tc->connection.lcl_ip.ip6))); + } + u8 is_valid = (tc->c_lcl_port == hdr->dst_port && (tc->state == TCP_STATE_LISTEN - || tc->c_rmt_port == hdr->src_port)); + || tc->c_rmt_port == hdr->src_port) && is_ip_valid); if (!is_valid) { @@ -2323,7 +2345,7 @@ tcp_lookup_connection (u32 fib_index, vlib_buffer_t * b, u8 thread_index, TRANSPORT_PROTO_TCP, thread_index, &is_filtered); tc = tcp_get_connection_from_transport (tconn); - ASSERT (tcp_lookup_is_valid (tc, tcp)); + ASSERT (tcp_lookup_is_valid (tc, b, tcp)); } else { @@ -2338,7 +2360,7 @@ tcp_lookup_connection (u32 fib_index, vlib_buffer_t * b, u8 thread_index, TRANSPORT_PROTO_TCP, thread_index, &is_filtered); tc = tcp_get_connection_from_transport (tconn); - ASSERT (tcp_lookup_is_valid (tc, tcp)); + ASSERT (tcp_lookup_is_valid (tc, b, tcp)); } return tc; } @@ -3551,8 +3573,8 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, if (PREDICT_TRUE (!tc0 + !tc1 == 0)) { - ASSERT (tcp_lookup_is_valid (tc0, tcp_buffer_hdr (b[0]))); - ASSERT (tcp_lookup_is_valid (tc1, tcp_buffer_hdr (b[1]))); + ASSERT (tcp_lookup_is_valid (tc0, b[0], tcp_buffer_hdr (b[0]))); + ASSERT (tcp_lookup_is_valid (tc1, b[1], tcp_buffer_hdr (b[1]))); vnet_buffer (b[0])->tcp.connection_index = tc0->c_c_index; vnet_buffer (b[1])->tcp.connection_index = tc1->c_c_index; @@ -3564,7 +3586,7 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, { if (PREDICT_TRUE (tc0 != 0)) { - ASSERT (tcp_lookup_is_valid (tc0, tcp_buffer_hdr (b[0]))); + ASSERT (tcp_lookup_is_valid (tc0, b[0], tcp_buffer_hdr (b[0]))); vnet_buffer (b[0])->tcp.connection_index = tc0->c_c_index; tcp_input_dispatch_buffer (tm, tc0, b[0], &next[0], &error0); } @@ -3573,7 +3595,7 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, if (PREDICT_TRUE (tc1 != 0)) { - ASSERT (tcp_lookup_is_valid (tc1, tcp_buffer_hdr (b[1]))); + ASSERT (tcp_lookup_is_valid (tc1, b[1], tcp_buffer_hdr (b[1]))); vnet_buffer (b[1])->tcp.connection_index = tc1->c_c_index; tcp_input_dispatch_buffer (tm, tc1, b[1], &next[1], &error1); } @@ -3601,7 +3623,7 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, is_nolookup); if (PREDICT_TRUE (tc0 != 0)) { - ASSERT (tcp_lookup_is_valid (tc0, tcp_buffer_hdr (b[0]))); + ASSERT (tcp_lookup_is_valid (tc0, b[0], tcp_buffer_hdr (b[0]))); vnet_buffer (b[0])->tcp.connection_index = tc0->c_c_index; tcp_input_dispatch_buffer (tm, tc0, b[0], &next[0], &error0); } -- cgit 1.2.3-korg