+static u8
+tcp_lookup_is_valid (tcp_connection_t * tc, tcp_header_t * hdr)
+{
+ transport_connection_t *tmp = 0;
+ u64 handle;
+
+ if (!tc)
+ return 1;
+
+ /* Proxy case */
+ if (tc->c_lcl_port == 0 && tc->state == TCP_STATE_LISTEN)
+ return 1;
+
+ u8 is_valid = (tc->c_lcl_port == hdr->dst_port
+ && (tc->state == TCP_STATE_LISTEN
+ || tc->c_rmt_port == hdr->src_port));
+
+ if (!is_valid)
+ {
+ handle = session_lookup_half_open_handle (&tc->connection);
+ tmp = session_lookup_half_open_connection (handle & 0xFFFFFFFF,
+ tc->c_proto, tc->c_is_ip4);
+
+ if (tmp)
+ {
+ if (tmp->lcl_port == hdr->dst_port
+ && tmp->rmt_port == hdr->src_port)
+ {
+ TCP_DBG ("half-open is valid!");
+ }
+ }
+ }
+ return is_valid;
+}
+
+/**
+ * Lookup transport connection
+ */
+static tcp_connection_t *
+tcp_lookup_connection (u32 fib_index, vlib_buffer_t * b, u8 thread_index,
+ u8 is_ip4)
+{
+ tcp_header_t *tcp;
+ transport_connection_t *tconn;
+ tcp_connection_t *tc;
+ u8 is_filtered = 0;
+ if (is_ip4)
+ {
+ ip4_header_t *ip4;
+ ip4 = vlib_buffer_get_current (b);
+ tcp = ip4_next_header (ip4);
+ tconn = session_lookup_connection_wt4 (fib_index,
+ &ip4->dst_address,
+ &ip4->src_address,
+ tcp->dst_port,
+ tcp->src_port,
+ TRANSPORT_PROTO_TCP,
+ thread_index, &is_filtered);
+ tc = tcp_get_connection_from_transport (tconn);
+ ASSERT (tcp_lookup_is_valid (tc, tcp));
+ }
+ else
+ {
+ ip6_header_t *ip6;
+ ip6 = vlib_buffer_get_current (b);
+ tcp = ip6_next_header (ip6);
+ tconn = session_lookup_connection_wt6 (fib_index,
+ &ip6->dst_address,
+ &ip6->src_address,
+ tcp->dst_port,
+ tcp->src_port,
+ TRANSPORT_PROTO_TCP,
+ thread_index, &is_filtered);
+ tc = tcp_get_connection_from_transport (tconn);
+ ASSERT (tcp_lookup_is_valid (tc, tcp));
+ }
+ return tc;
+}
+