tcp: avoid fr segments less than mss if possible
[vpp.git] / src / vnet / tcp / tcp.c
index d0d8158..efc72a2 100644 (file)
@@ -25,6 +25,8 @@
 #include <vnet/dpo/load_balance.h>
 #include <math.h>
 
+#include <vlib/stats/stats.h>
+
 tcp_main_t tcp_main;
 
 typedef struct
@@ -408,8 +410,8 @@ tcp_connection_close (tcp_connection_t * tc)
     case TCP_STATE_CLOSE_WAIT:
       if (!transport_max_tx_dequeue (&tc->connection))
        {
-         tcp_send_fin (tc);
          tcp_connection_timers_reset (tc);
+         tcp_send_fin (tc);
          tcp_connection_set_state (tc, TCP_STATE_LAST_ACK);
          tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_WAITCLOSE,
                            tcp_cfg.lastack_time);
@@ -489,6 +491,14 @@ tcp_session_reset (u32 conn_index, u32 thread_index)
 {
   tcp_connection_t *tc;
   tc = tcp_connection_get (conn_index, thread_index);
+
+  /* For half-opens just cleanup */
+  if (tc->state == TCP_STATE_SYN_SENT)
+    {
+      tcp_connection_cleanup (tc);
+      return;
+    }
+
   tcp_send_reset (tc);
   tcp_connection_timers_reset (tc);
   tcp_cong_recovery_off (tc);
@@ -821,7 +831,7 @@ tcp_session_open (transport_endpoint_cfg_t * rmt)
   ip_copy (&tc->c_rmt_ip, &rmt->ip, rmt->is_ip4);
   ip_copy (&tc->c_lcl_ip, &lcl_addr, rmt->is_ip4);
   tc->c_rmt_port = rmt->port;
-  tc->c_lcl_port = clib_host_to_net_u16 (lcl_port);
+  tc->c_lcl_port = lcl_port;
   tc->c_is_ip4 = rmt->is_ip4;
   tc->c_proto = TRANSPORT_PROTO_TCP;
   tc->c_fib_index = rmt->fib_index;
@@ -1213,7 +1223,6 @@ tcp_timer_waitclose_handler (tcp_connection_t * tc)
     }
 }
 
-/* *INDENT-OFF* */
 static timer_expiration_handler *timer_expiration_handlers[TCP_N_TIMERS] =
 {
     tcp_timer_retransmit_handler,
@@ -1221,7 +1230,6 @@ static timer_expiration_handler *timer_expiration_handlers[TCP_N_TIMERS] =
     tcp_timer_waitclose_handler,
     tcp_timer_retransmit_syn_handler,
 };
-/* *INDENT-ON* */
 
 static void
 tcp_dispatch_pending_timers (tcp_worker_ctx_t * wrk)
@@ -1329,7 +1337,6 @@ tcp_session_app_rx_evt (transport_connection_t *conn)
   return 0;
 }
 
-/* *INDENT-OFF* */
 const static transport_proto_vft_t tcp_proto = {
   .enable = vnet_tcp_enable_disable,
   .start_listen = tcp_session_bind,
@@ -1360,7 +1367,6 @@ const static transport_proto_vft_t tcp_proto = {
     .service_type = TRANSPORT_SERVICE_VC,
   },
 };
-/* *INDENT-ON* */
 
 void
 tcp_connection_tx_pacer_update (tcp_connection_t * tc)
@@ -1450,6 +1456,51 @@ tcp_initialize_iss_seed (tcp_main_t * tm)
   tm->iss_seed.second = random_u64 (&time_now);
 }
 
+static void
+tcp_stats_collector_fn (vlib_stats_collector_data_t *d)
+{
+  tcp_main_t *tm = vnet_get_tcp_main ();
+  counter_t **counters = d->entry->data;
+  counter_t *cb = counters[0];
+  tcp_wrk_stats_t acc = {};
+  tcp_worker_ctx_t *wrk;
+
+  vec_foreach (wrk, tm->wrk_ctx)
+    {
+#define _(name, type, str) acc.name += wrk->stats.name;
+      foreach_tcp_wrk_stat
+#undef _
+    }
+
+#define _(name, type, str) cb[TCP_STAT_##name] = acc.name;
+  foreach_tcp_wrk_stat
+#undef _
+}
+
+static void
+tcp_counters_init (tcp_main_t *tm)
+{
+  vlib_stats_collector_reg_t r = {};
+  u32 idx;
+
+  if (tm->counters_init)
+    return;
+
+  r.entry_index = idx = vlib_stats_add_counter_vector ("/sys/tcp");
+  r.collect_fn = tcp_stats_collector_fn;
+  vlib_stats_validate (idx, 0, TCP_STAT_no_buffer);
+
+#define _(name, type, str)                                                    \
+  vlib_stats_add_symlink (idx, TCP_STAT_##name, "/sys/tcp/%s",                \
+                         CLIB_STRING_MACRO (name));
+  foreach_tcp_wrk_stat
+#undef _
+
+    vlib_stats_register_collector_fn (&r);
+
+  tm->counters_init = 1;
+}
+
 static clib_error_t *
 tcp_main_enable (vlib_main_t * vm)
 {
@@ -1526,6 +1577,8 @@ tcp_main_enable (vlib_main_t * vm)
   tm->bytes_per_buffer = vlib_buffer_get_default_data_size (vm);
   tm->cc_last_type = TCP_CC_LAST;
 
+  tcp_counters_init (tm);
+
   return error;
 }