tcp: move accept init to separate reusable function
Type: refactor
Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I5120eb321e9e2050eb64dca9e2dfb6256ff2b62d
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c
index dfcce77..8a09b56 100644
--- a/src/vnet/tcp/tcp.c
+++ b/src/vnet/tcp/tcp.c
@@ -707,6 +707,51 @@
tc->start_ts = tcp_time_now_us (tc->c_thread_index);
}
+void
+tcp_init_w_buffer (tcp_connection_t * tc, vlib_buffer_t * b, u8 is_ip4)
+{
+ tcp_header_t *th = tcp_buffer_hdr (b);
+
+ tc->c_lcl_port = th->dst_port;
+ tc->c_rmt_port = th->src_port;
+ tc->c_is_ip4 = is_ip4;
+
+ if (is_ip4)
+ {
+ ip4_header_t *ip4 = vlib_buffer_get_current (b);
+ tc->c_lcl_ip4.as_u32 = ip4->dst_address.as_u32;
+ tc->c_rmt_ip4.as_u32 = ip4->src_address.as_u32;
+ }
+ else
+ {
+ ip6_header_t *ip6 = vlib_buffer_get_current (b);
+ clib_memcpy_fast (&tc->c_lcl_ip6, &ip6->dst_address,
+ sizeof (ip6_address_t));
+ clib_memcpy_fast (&tc->c_rmt_ip6, &ip6->src_address,
+ sizeof (ip6_address_t));
+ }
+
+ tc->irs = vnet_buffer (b)->tcp.seq_number;
+ tc->rcv_nxt = vnet_buffer (b)->tcp.seq_number + 1;
+ tc->rcv_las = tc->rcv_nxt;
+ tc->sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
+ tc->snd_wl1 = vnet_buffer (b)->tcp.seq_number;
+ tc->snd_wl2 = vnet_buffer (b)->tcp.ack_number;
+
+ /* RFC1323: TSval timestamps sent on {SYN} and {SYN,ACK}
+ * segments are used to initialize PAWS. */
+ if (tcp_opts_tstamp (&tc->rcv_opts))
+ {
+ tc->tsval_recent = tc->rcv_opts.tsval;
+ tc->tsval_recent_age = tcp_time_now ();
+ }
+
+ if (tcp_opts_wscale (&tc->rcv_opts))
+ tc->snd_wscale = tc->rcv_opts.wscale;
+
+ tc->snd_wnd = clib_net_to_host_u16 (th->window) << tc->snd_wscale;
+}
+
static int
tcp_alloc_custom_local_endpoint (tcp_main_t * tm, ip46_address_t * lcl_addr,
u16 * lcl_port, u8 is_ip4)
diff --git a/src/vnet/tcp/tcp.h b/src/vnet/tcp/tcp.h
index 4db6040..9988069 100644
--- a/src/vnet/tcp/tcp.h
+++ b/src/vnet/tcp/tcp.h
@@ -1301,6 +1301,14 @@
void newreno_rcv_cong_ack (tcp_connection_t * tc, tcp_cc_ack_t ack_type,
tcp_rate_sample_t * rs);
+/**
+ * Initialize connection by gleaning network and rcv params from buffer
+ *
+ * @param tc connection to initialize
+ * @param b buffer whose current data is pointing at ip
+ * @param is_ip4 flag set to 1 if using ip4
+ */
+void tcp_init_w_buffer (tcp_connection_t * tc, vlib_buffer_t * b, u8 is_ip4);
/**
* Push TCP header to buffer
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c
index bac4147..0757741 100755
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -3314,54 +3314,46 @@
vlib_frame_t * from_frame, int is_ip4)
{
u32 n_left_from, *from, n_syns = 0, *first_buffer;
- u32 my_thread_index = vm->thread_index;
- tcp_connection_t *tc0;
+ u32 thread_index = vm->thread_index;
from = first_buffer = vlib_frame_vector_args (from_frame);
n_left_from = from_frame->n_vectors;
while (n_left_from > 0)
{
- u32 bi0;
- vlib_buffer_t *b0;
- tcp_rx_trace_t *t0;
- tcp_header_t *th0 = 0;
- tcp_connection_t *lc0;
- ip4_header_t *ip40;
- ip6_header_t *ip60;
- tcp_connection_t *child0;
- u32 error0 = TCP_ERROR_NONE;
+ u32 bi, error = TCP_ERROR_NONE;
+ tcp_connection_t *lc, *child;
+ vlib_buffer_t *b;
- bi0 = from[0];
+ bi = from[0];
from += 1;
n_left_from -= 1;
- b0 = vlib_get_buffer (vm, bi0);
+ b = vlib_get_buffer (vm, bi);
- if (is_ip4)
+ lc = tcp_listener_get (vnet_buffer (b)->tcp.connection_index);
+ if (PREDICT_FALSE (lc == 0))
{
- ip40 = vlib_buffer_get_current (b0);
- th0 = tcp_buffer_hdr (b0);
- }
- else
- {
- ip60 = vlib_buffer_get_current (b0);
- th0 = tcp_buffer_hdr (b0);
- }
-
- lc0 = tcp_listener_get (vnet_buffer (b0)->tcp.connection_index);
- if (PREDICT_FALSE (lc0 == 0))
- {
- tc0 = tcp_connection_get (vnet_buffer (b0)->tcp.connection_index,
- my_thread_index);
- if (tc0->state != TCP_STATE_TIME_WAIT)
+ tcp_connection_t *tc;
+ tc = tcp_connection_get (vnet_buffer (b)->tcp.connection_index,
+ thread_index);
+ if (tc->state != TCP_STATE_TIME_WAIT)
{
- error0 = TCP_ERROR_CREATE_EXISTS;
- goto drop;
+ error = TCP_ERROR_CREATE_EXISTS;
+ goto done;
}
- lc0 = tcp_lookup_listener (b0, tc0->c_fib_index, is_ip4);
+ lc = tcp_lookup_listener (b, tc->c_fib_index, is_ip4);
/* clean up the old session */
- tcp_connection_del (tc0);
+ tcp_connection_del (tc);
+ }
+
+ /* Make sure connection wasn't just created */
+ child = tcp_lookup_connection (lc->c_fib_index, b, thread_index,
+ is_ip4);
+ if (PREDICT_FALSE (child->state != TCP_STATE_LISTEN))
+ {
+ error = TCP_ERROR_CREATE_EXISTS;
+ goto done;
}
/* Create child session. For syn-flood protection use filter */
@@ -3381,91 +3373,51 @@
/* 3. check for a SYN (did that already) */
- /* Make sure connection wasn't just created */
- child0 = tcp_lookup_connection (lc0->c_fib_index, b0, my_thread_index,
- is_ip4);
- if (PREDICT_FALSE (child0->state != TCP_STATE_LISTEN))
- {
- error0 = TCP_ERROR_CREATE_EXISTS;
- goto drop;
- }
-
/* Create child session and send SYN-ACK */
- child0 = tcp_connection_alloc (my_thread_index);
- child0->c_lcl_port = th0->dst_port;
- child0->c_rmt_port = th0->src_port;
- child0->c_is_ip4 = is_ip4;
- child0->state = TCP_STATE_SYN_RCVD;
- child0->c_fib_index = lc0->c_fib_index;
- child0->cc_algo = lc0->cc_algo;
+ child = tcp_connection_alloc (thread_index);
- if (is_ip4)
+ if (tcp_options_parse (tcp_buffer_hdr (b), &child->rcv_opts, 1))
{
- child0->c_lcl_ip4.as_u32 = ip40->dst_address.as_u32;
- child0->c_rmt_ip4.as_u32 = ip40->src_address.as_u32;
- }
- else
- {
- clib_memcpy_fast (&child0->c_lcl_ip6, &ip60->dst_address,
- sizeof (ip6_address_t));
- clib_memcpy_fast (&child0->c_rmt_ip6, &ip60->src_address,
- sizeof (ip6_address_t));
+ error = TCP_ERROR_OPTIONS;
+ tcp_connection_free (child);
+ goto done;
}
- if (tcp_options_parse (th0, &child0->rcv_opts, 1))
+ tcp_init_w_buffer (child, b, is_ip4);
+
+ child->state = TCP_STATE_SYN_RCVD;
+ child->c_fib_index = lc->c_fib_index;
+ child->cc_algo = lc->cc_algo;
+ tcp_connection_init_vars (child);
+ child->rto = TCP_RTO_MIN;
+
+ if (session_stream_accept (&child->connection, lc->c_s_index,
+ lc->c_thread_index, 0 /* notify */ ))
{
- error0 = TCP_ERROR_OPTIONS;
- tcp_connection_free (child0);
- goto drop;
+ tcp_connection_cleanup (child);
+ error = TCP_ERROR_CREATE_SESSION_FAIL;
+ goto done;
}
- child0->irs = vnet_buffer (b0)->tcp.seq_number;
- child0->rcv_nxt = vnet_buffer (b0)->tcp.seq_number + 1;
- child0->rcv_las = child0->rcv_nxt;
- child0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
+ child->tx_fifo_size = transport_tx_fifo_size (&child->connection);
- /* RFC1323: TSval timestamps sent on {SYN} and {SYN,ACK}
- * segments are used to initialize PAWS. */
- if (tcp_opts_tstamp (&child0->rcv_opts))
+ tcp_send_synack (child);
+
+ TCP_EVT (TCP_EVT_SYN_RCVD, child, 1);
+
+ done:
+
+ if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
{
- child0->tsval_recent = child0->rcv_opts.tsval;
- child0->tsval_recent_age = tcp_time_now ();
+ tcp_rx_trace_t *t;
+ t = vlib_add_trace (vm, node, b, sizeof (*t));
+ clib_memcpy_fast (&t->tcp_header, tcp_buffer_hdr (b),
+ sizeof (t->tcp_header));
+ clib_memcpy_fast (&t->tcp_connection, lc,
+ sizeof (t->tcp_connection));
}
- if (tcp_opts_wscale (&child0->rcv_opts))
- child0->snd_wscale = child0->rcv_opts.wscale;
-
- child0->snd_wnd = clib_net_to_host_u16 (th0->window)
- << child0->snd_wscale;
- child0->snd_wl1 = vnet_buffer (b0)->tcp.seq_number;
- child0->snd_wl2 = vnet_buffer (b0)->tcp.ack_number;
-
- tcp_connection_init_vars (child0);
- child0->rto = TCP_RTO_MIN;
-
- if (session_stream_accept (&child0->connection, lc0->c_s_index,
- lc0->c_thread_index, 0 /* notify */ ))
- {
- tcp_connection_cleanup (child0);
- error0 = TCP_ERROR_CREATE_SESSION_FAIL;
- goto drop;
- }
-
- TCP_EVT (TCP_EVT_SYN_RCVD, child0, 1);
- child0->tx_fifo_size = transport_tx_fifo_size (&child0->connection);
- tcp_send_synack (child0);
-
- drop:
-
- if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
- {
- t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
- clib_memcpy_fast (&t0->tcp_header, th0, sizeof (t0->tcp_header));
- clib_memcpy_fast (&t0->tcp_connection, lc0,
- sizeof (t0->tcp_connection));
- }
-
- n_syns += (error0 == TCP_ERROR_NONE);
+ n_syns += (error == TCP_ERROR_NONE);
}
tcp_inc_counter (listen, TCP_ERROR_SYNS_RCVD, n_syns);