From dff48db0782444125f68cab14d91e7bb4109286a Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Sun, 19 Nov 2017 18:06:58 -0800 Subject: session/tcp: filtering improvements - make allow action explicit (-3) - add session lookup is_filtered return flag that is set if lookup hit a deny filter - change tcp logic to drop filtered packets when punting is enabled Change-Id: Ic38f294424663a4e108439b7571511f46f8e0be1 Signed-off-by: Florin Coras --- src/vnet/tcp/tcp_error.def | 3 ++- src/vnet/tcp/tcp_input.c | 36 ++++++++++++++++++++++-------------- src/vnet/tcp/tcp_test.c | 12 ++++++------ 3 files changed, 30 insertions(+), 21 deletions(-) (limited to 'src/vnet/tcp') diff --git a/src/vnet/tcp/tcp_error.def b/src/vnet/tcp/tcp_error.def index a179717ff13..5bff5ee5d4a 100644 --- a/src/vnet/tcp/tcp_error.def +++ b/src/vnet/tcp/tcp_error.def @@ -40,4 +40,5 @@ tcp_error (INVALID_CONNECTION, "Invalid connection") tcp_error (NO_WND, "No window") tcp_error (CONNECTION_CLOSED, "Connection closed") tcp_error (CREATE_EXISTS, "Connection already exists") -tcp_error (PUNT, "Packets punted") \ No newline at end of file +tcp_error (PUNT, "Packets punted") +tcp_error (FILTERED, "Packets filtered") \ No newline at end of file diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c index 6d7bebadfeb..d3db7ef1eec 100644 --- a/src/vnet/tcp/tcp_input.c +++ b/src/vnet/tcp/tcp_input.c @@ -1902,6 +1902,7 @@ tcp_lookup_connection (u32 fib_index, vlib_buffer_t * b, u8 thread_index, tcp_header_t *tcp; transport_connection_t *tconn; tcp_connection_t *tc; + u8 is_filtered = 0; if (is_ip4) { ip4_header_t *ip4; @@ -1913,7 +1914,7 @@ tcp_lookup_connection (u32 fib_index, vlib_buffer_t * b, u8 thread_index, tcp->dst_port, tcp->src_port, TRANSPORT_PROTO_TCP, - thread_index); + thread_index, &is_filtered); tc = tcp_get_connection_from_transport (tconn); ASSERT (tcp_lookup_is_valid (tc, tcp)); } @@ -1928,7 +1929,7 @@ tcp_lookup_connection (u32 fib_index, vlib_buffer_t * b, u8 thread_index, tcp->dst_port, tcp->src_port, TRANSPORT_PROTO_TCP, - thread_index); + thread_index, &is_filtered); tc = tcp_get_connection_from_transport (tconn); ASSERT (tcp_lookup_is_valid (tc, tcp)); } @@ -2939,7 +2940,7 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, ip4_header_t *ip40; ip6_header_t *ip60; u32 error0 = TCP_ERROR_NO_LISTENER, next0 = TCP_INPUT_NEXT_DROP; - u8 flags0; + u8 flags0, is_filtered = 0; bi0 = from[0]; to_next[0] = bi0; @@ -2968,9 +2969,8 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, tcp0->dst_port, tcp0->src_port, TRANSPORT_PROTO_TCP, - my_thread_index); - tc0 = tcp_get_connection_from_transport (tconn); - ASSERT (tcp_lookup_is_valid (tc0, tcp0)); + my_thread_index, + &is_filtered); } else { @@ -2986,9 +2986,8 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, tcp0->dst_port, tcp0->src_port, TRANSPORT_PROTO_TCP, - my_thread_index); - tc0 = tcp_get_connection_from_transport (tconn); - ASSERT (tcp_lookup_is_valid (tc0, tcp0)); + my_thread_index, + &is_filtered); } /* Length check */ @@ -2999,8 +2998,11 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, } /* Session exists */ - if (PREDICT_TRUE (0 != tc0)) + if (PREDICT_TRUE (0 != tconn)) { + tc0 = tcp_get_connection_from_transport (tconn); + ASSERT (tcp_lookup_is_valid (tc0, tcp0)); + /* Save connection index */ vnet_buffer (b0)->tcp.connection_index = tc0->c_c_index; vnet_buffer (b0)->tcp.seq_number = @@ -3032,8 +3034,13 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, } else { - if ((is_ip4 && tm->punt_unknown4) || - (!is_ip4 && tm->punt_unknown6)) + if (is_filtered) + { + next0 = TCP_INPUT_NEXT_DROP; + error0 = TCP_ERROR_FILTERED; + } + else if ((is_ip4 && tm->punt_unknown4) || + (!is_ip4 && tm->punt_unknown6)) { next0 = TCP_INPUT_NEXT_PUNT; error0 = TCP_ERROR_PUNT; @@ -3044,6 +3051,7 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, next0 = TCP_INPUT_NEXT_RESET; error0 = TCP_ERROR_NO_LISTENER; } + tc0 = 0; } done: @@ -3051,8 +3059,8 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) { - tcp_rx_trace_t *t0 = - vlib_add_trace (vm, node, b0, sizeof (*t0)); + tcp_rx_trace_t *t0; + t0 = vlib_add_trace (vm, node, b0, sizeof (*t0)); tcp_set_rx_trace_data (t0, tc0, tcp0, b0, is_ip4); } vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, diff --git a/src/vnet/tcp/tcp_test.c b/src/vnet/tcp/tcp_test.c index 021f416cb76..e3cdb1be758 100644 --- a/src/vnet/tcp/tcp_test.c +++ b/src/vnet/tcp/tcp_test.c @@ -1558,7 +1558,7 @@ tcp_test_lookup (vlib_main_t * vm, unformat_input_t * input) transport_connection_t _tc1, *tc1 = &_tc1, _tc2, *tc2 = &_tc2, *tconn; tcp_connection_t *tc; stream_session_t *s; - u8 cmp = 0; + u8 cmp = 0, is_filtered = 0; pool_get (smm->sessions[0], s); memset (s, 0, sizeof (*s)); @@ -1601,7 +1601,7 @@ tcp_test_lookup (vlib_main_t * vm, unformat_input_t * input) tconn = session_lookup_connection_wt4 (0, &tc1->lcl_ip.ip4, &tc1->rmt_ip.ip4, tc1->lcl_port, tc1->rmt_port, - tc1->proto, 0); + tc1->proto, 0, &is_filtered); cmp = (memcmp (&tconn->rmt_ip, &tc1->rmt_ip, sizeof (tc1->rmt_ip)) == 0); TCP_TEST ((cmp), "rmt ip is identical %d", cmp); TCP_TEST ((tconn->lcl_port == tc1->lcl_port), @@ -1614,7 +1614,7 @@ tcp_test_lookup (vlib_main_t * vm, unformat_input_t * input) tconn = session_lookup_connection_wt4 (0, &tc2->lcl_ip.ip4, &tc2->rmt_ip.ip4, tc2->lcl_port, tc2->rmt_port, - tc2->proto, 0); + tc2->proto, 0, &is_filtered); TCP_TEST ((tconn == 0), "lookup result should be null"); /* @@ -1624,12 +1624,12 @@ tcp_test_lookup (vlib_main_t * vm, unformat_input_t * input) tconn = session_lookup_connection_wt4 (0, &tc1->lcl_ip.ip4, &tc1->rmt_ip.ip4, tc1->lcl_port, tc1->rmt_port, - tc1->proto, 0); + tc1->proto, 0, &is_filtered); TCP_TEST ((tconn == 0), "lookup result should be null"); tconn = session_lookup_connection_wt4 (0, &tc2->lcl_ip.ip4, &tc2->rmt_ip.ip4, tc2->lcl_port, tc2->rmt_port, - tc2->proto, 0); + tc2->proto, 0, &is_filtered); TCP_TEST ((tconn == 0), "lookup result should be null"); /* @@ -1639,7 +1639,7 @@ tcp_test_lookup (vlib_main_t * vm, unformat_input_t * input) tconn = session_lookup_connection_wt4 (0, &tc2->lcl_ip.ip4, &tc2->rmt_ip.ip4, tc2->lcl_port, tc2->rmt_port, - tc2->proto, 0); + tc2->proto, 0, &is_filtered); TCP_TEST ((tconn == 0), "lookup result should be null"); return 0; -- cgit 1.2.3-korg