session tcp vcl: api to update connection attributes
[vpp.git] / src / vnet / tcp / tcp_input.c
index 0a3d315..398bf1b 100644 (file)
@@ -149,7 +149,7 @@ tcp_update_timestamp (tcp_connection_t * tc, u32 seq, u32 seq_end)
     {
       ASSERT (timestamp_leq (tc->tsval_recent, tc->rcv_opts.tsval));
       tc->tsval_recent = tc->rcv_opts.tsval;
-      tc->tsval_recent_age = tcp_time_now_w_thread (tc->c_thread_index);
+      tc->tsval_recent_age = tcp_time_tstamp (tc->c_thread_index);
     }
 }
 
@@ -288,7 +288,7 @@ tcp_segment_validate (tcp_worker_ctx_t * wrk, tcp_connection_t * tc0,
       /* If it just so happens that a segment updates tsval_recent for a
        * segment over 24 days old, invalidate tsval_recent. */
       if (timestamp_lt (tc0->tsval_recent_age + TCP_PAWS_IDLE,
-                       tcp_time_now_w_thread (tc0->c_thread_index)))
+                       tcp_time_tstamp (tc0->c_thread_index)))
        {
          tc0->tsval_recent = tc0->rcv_opts.tsval;
          clib_warning ("paws failed: 24-day old segment");
@@ -1776,7 +1776,7 @@ tcp_check_tx_offload (tcp_connection_t * tc, int is_ipv4)
     return;
 
   hw_if = vnet_get_sup_hw_interface (vnm, sw_if_idx);
-  if (hw_if->flags & VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO)
+  if (hw_if->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO)
     tc->cfg_flags |= TCP_CFG_F_TSO;
 }
 
@@ -1812,13 +1812,10 @@ tcp46_syn_sent_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
          goto drop;
        }
 
-      /* Half-open completed recently but the connection was't removed
-       * yet by the owning thread */
+      /* Half-open completed or cancelled recently but the connection
+       * was't removed yet by the owning thread */
       if (PREDICT_FALSE (tc0->flags & TCP_CONN_HALF_OPEN_DONE))
        {
-         /* Make sure the connection actually exists */
-         ASSERT (tcp_lookup_connection (tc0->c_fib_index, b0,
-                                        my_thread_index, is_ip4));
          error0 = TCP_ERROR_SPURIOUS_SYN_ACK;
          goto drop;
        }
@@ -1923,7 +1920,7 @@ tcp46_syn_sent_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
       if (tcp_opts_tstamp (&new_tc0->rcv_opts))
        {
          new_tc0->tsval_recent = new_tc0->rcv_opts.tsval;
-         new_tc0->tsval_recent_age = tcp_time_now ();
+         new_tc0->tsval_recent_age = tcp_time_tstamp (my_thread_index);
        }
 
       if (tcp_opts_wscale (&new_tc0->rcv_opts))
@@ -2564,14 +2561,19 @@ tcp46_listen_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
 
       b = vlib_get_buffer (vm, bi);
 
-      lc = tcp_listener_get (vnet_buffer (b)->tcp.connection_index);
-      if (PREDICT_FALSE (lc == 0))
+      /* Flags initialized with connection state after lookup */
+      if (vnet_buffer (b)->tcp.flags == TCP_STATE_LISTEN)
+       {
+         lc = tcp_listener_get (vnet_buffer (b)->tcp.connection_index);
+       }
+      else
        {
          tcp_connection_t *tc;
          tc = tcp_connection_get (vnet_buffer (b)->tcp.connection_index,
                                   thread_index);
          if (tc->state != TCP_STATE_TIME_WAIT)
            {
+             lc = 0;
              error = TCP_ERROR_CREATE_EXISTS;
              goto done;
            }
@@ -2805,6 +2807,10 @@ tcp_input_dispatch_buffer (tcp_main_t * tm, tcp_connection_t * tc,
   error = tm->dispatch_table[tc->state][flags].error;
   tc->segs_in += 1;
 
+  /* Track connection state when packet was received. It helps
+   * @ref tcp46_listen_inline detect port reuse */
+  vnet_buffer (b)->tcp.flags = tc->state;
+
   if (PREDICT_FALSE (error != TCP_ERROR_NONE))
     {
       b->error = error_node->errors[error];
@@ -2824,7 +2830,7 @@ tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
   vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
   u16 nexts[VLIB_FRAME_SIZE], *next;
 
-  tcp_set_time_now (tcp_get_worker (thread_index));
+  tcp_update_time_now (tcp_get_worker (thread_index));
 
   from = vlib_frame_vector_args (frame);
   n_left_from = frame->n_vectors;
@@ -3044,6 +3050,12 @@ VLIB_REGISTER_NODE (tcp6_input_node) =
 /* *INDENT-ON* */
 
 #ifndef CLIB_MARCH_VARIANT
+void
+tcp_check_gso (tcp_connection_t *tc)
+{
+  tcp_check_tx_offload (tc, tc->c_is_ip4);
+}
+
 static void
 tcp_dispatch_table_init (tcp_main_t * tm)
 {