tcp: custom checksum calculations for Ipv4/Ipv6
[vpp.git] / src / vnet / tcp / tcp.h
index 99735f2..1bf3281 100644 (file)
@@ -32,6 +32,7 @@
 #define TCP_MAX_OPTION_SPACE 40
 #define TCP_CC_DATA_SZ 24
 #define TCP_MAX_GSO_SZ 65536
+#define TCP_RXT_MAX_BURST 10
 
 #define TCP_DUPACK_THRESHOLD   3
 #define TCP_IW_N_SEGMENTS      10
@@ -111,7 +112,7 @@ extern timer_expiration_handler tcp_timer_retransmit_syn_handler;
   _(DCNT_PENDING, "Disconnect pending")                \
   _(HALF_OPEN_DONE, "Half-open completed")     \
   _(FINPNDG, "FIN pending")                    \
-  _(FRXT_PENDING, "Fast-retransmit pending")   \
+  _(RXT_PENDING, "Retransmit pending")         \
   _(FRXT_FIRST, "Fast-retransmit first again") \
   _(DEQ_PENDING, "Pending dequeue acked")      \
   _(PSH_PENDING, "PSH pending")                        \
@@ -119,6 +120,7 @@ extern timer_expiration_handler tcp_timer_retransmit_syn_handler;
   _(RATE_SAMPLE, "Conn does rate sampling")    \
   _(TRACK_BURST, "Track burst")                        \
   _(ZERO_RWND_SENT, "Zero RWND sent")          \
+  _(NO_CSUM_OFFLOAD, "No Checksum Offload")     \
 
 typedef enum _tcp_connection_flag_bits
 {
@@ -166,13 +168,14 @@ typedef struct _sack_scoreboard
   u32 sacked_bytes;                    /**< Number of bytes sacked in sb */
   u32 last_sacked_bytes;               /**< Number of bytes last sacked */
   u32 last_bytes_delivered;            /**< Sack bytes delivered to app */
-  u32 snd_una_adv;                     /**< Bytes to add to snd_una */
+  u32 rxt_sacked;                      /**< Rxt last delivered */
   u32 high_sacked;                     /**< Highest byte sacked (fack) */
   u32 high_rxt;                                /**< Highest retransmitted sequence */
   u32 rescue_rxt;                      /**< Rescue sequence number */
   u32 lost_bytes;                      /**< Bytes lost as per RFC6675 */
   u32 last_lost_bytes;                 /**< Number of bytes last lost */
   u32 cur_rxt_hole;                    /**< Retransmitting from this hole */
+  u8 is_reneging;
 
 #if TCP_SCOREBOARD_TRACE
   scoreboard_trace_elt_t *trace;
@@ -219,8 +222,11 @@ sack_scoreboard_hole_t *scoreboard_prev_hole (sack_scoreboard_t * sb,
                                              sack_scoreboard_hole_t * hole);
 sack_scoreboard_hole_t *scoreboard_first_hole (sack_scoreboard_t * sb);
 sack_scoreboard_hole_t *scoreboard_last_hole (sack_scoreboard_t * sb);
+
 void scoreboard_clear (sack_scoreboard_t * sb);
+void scoreboard_clear_reneging (sack_scoreboard_t * sb, u32 start, u32 end);
 void scoreboard_init (sack_scoreboard_t * sb);
+void scoreboard_init_high_rxt (sack_scoreboard_t * sb, u32 snd_una);
 u8 *format_tcp_scoreboard (u8 * s, va_list * args);
 
 #define TCP_BTS_INVALID_INDEX  ((u32)~0)
@@ -240,7 +246,7 @@ typedef struct tcp_bt_sample_
   u64 delivered;               /**< Total delivered bytes for sample */
   f64 delivered_time;          /**< Delivered time when sample taken */
   f64 tx_time;                 /**< Transmit time for the burst */
-  u64 tx_rate;                 /**< Tx pacing rate */
+  f64 first_tx_time;           /**< Connection first tx time at tx */
   tcp_bts_flags_t flags;       /**< Sample flag */
 } tcp_bt_sample_t;
 
@@ -251,7 +257,6 @@ typedef struct tcp_rate_sample_
   f64 prior_time;              /**< Delivered time of sample used for rate */
   f64 interval_time;           /**< Time to ack the bytes delivered */
   f64 rtt_time;                        /**< RTT for sample */
-  u64 tx_rate;                 /**< Tx pacing rate */
   u32 delivered;               /**< Bytes delivered in interval_time */
   u32 acked_and_sacked;                /**< Bytes acked + sacked now */
   u32 lost;                    /**< Bytes lost now */
@@ -361,8 +366,10 @@ typedef struct _tcp_connection
   u32 prev_cwnd;       /**< ssthresh before congestion */
   u32 bytes_acked;     /**< Bytes acknowledged by current segment */
   u32 burst_acked;     /**< Bytes acknowledged in current burst */
-  u32 snd_rxt_bytes;   /**< Retransmitted bytes */
+  u32 snd_rxt_bytes;   /**< Retransmitted bytes during current cc event */
   u32 snd_rxt_ts;      /**< Timestamp when first packet is retransmitted */
+  u32 prr_delivered;   /**< RFC6937 bytes delivered during current event */
+  u32 rxt_delivered;   /**< Rxt bytes delivered during current cc event */
   u32 tsecr_last_ack;  /**< Timestamp echoed to us in last healthy ACK */
   u32 snd_congestion;  /**< snd_una_max when congestion is detected */
   u32 tx_fifo_size;    /**< Tx fifo size. Used to constrain cwnd */
@@ -394,6 +401,7 @@ typedef struct _tcp_connection
   u64 delivered;               /**< Total bytes delivered to peer */
   u64 app_limited;             /**< Delivered when app-limited detected */
   f64 delivered_time;          /**< Time last bytes were acked */
+  f64 first_tx_time;           /**< Send time for recently delivered/sent */
   tcp_byte_tracker_t *bt;      /**< Tx byte tracker */
 
   tcp_errors_t errors; /**< Soft connection errors */
@@ -757,7 +765,7 @@ void tcp_send_window_update_ack (tcp_connection_t * tc);
 
 void tcp_program_ack (tcp_connection_t * tc);
 void tcp_program_dupack (tcp_connection_t * tc);
-void tcp_program_fastretransmit (tcp_connection_t * tc);
+void tcp_program_retransmit (tcp_connection_t * tc);
 
 /*
  * Rate estimation
@@ -857,18 +865,9 @@ tcp_flight_size (const tcp_connection_t * tc)
   int flight_size;
 
   flight_size = (int) (tc->snd_nxt - tc->snd_una) - tcp_bytes_out (tc)
-    + tc->snd_rxt_bytes;
+    + tc->snd_rxt_bytes - tc->rxt_delivered;
 
-  if (flight_size < 0)
-    {
-      if (0)
-       clib_warning
-         ("Negative: %u %u %u dupacks %u sacked bytes %u flags %d",
-          tc->snd_una_max - tc->snd_una, tcp_bytes_out (tc),
-          tc->snd_rxt_bytes, tc->rcv_dupacks, tc->sack_sb.sacked_bytes,
-          tc->rcv_opts.flags);
-      return 0;
-    }
+  ASSERT (flight_size >= 0);
 
   return flight_size;
 }
@@ -912,7 +911,8 @@ tcp_cwnd_accumulate (tcp_connection_t * tc, u32 thresh, u32 bytes)
 always_inline u32
 tcp_loss_wnd (const tcp_connection_t * tc)
 {
-  return tc->snd_mss;
+  /* Whatever we have in flight + the packet we're about to send */
+  return tcp_flight_size (tc) + tc->snd_mss;
 }
 
 always_inline u32
@@ -951,22 +951,14 @@ tcp_available_cc_snd_space (const tcp_connection_t * tc)
 always_inline u8
 tcp_is_lost_fin (tcp_connection_t * tc)
 {
-  if ((tc->flags & TCP_CONN_FINSNT) && tc->snd_una_max - tc->snd_una == 1)
+  if ((tc->flags & TCP_CONN_FINSNT) && (tc->snd_una_max - tc->snd_una == 1))
     return 1;
   return 0;
 }
 
 u32 tcp_snd_space (tcp_connection_t * tc);
-int tcp_retransmit_first_unacked (tcp_worker_ctx_t * wrk,
-                                 tcp_connection_t * tc);
-int tcp_fast_retransmit_no_sack (tcp_worker_ctx_t * wrk,
-                                tcp_connection_t * tc, u32 burst_size);
-int tcp_fast_retransmit_sack (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
-                             u32 burst_size);
-int tcp_fast_retransmit (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
-                        u32 burst_size);
-void tcp_cc_init_congestion (tcp_connection_t * tc);
-void tcp_cc_fastrecovery_clear (tcp_connection_t * tc);
+//void tcp_cc_init_congestion (tcp_connection_t * tc);
+//void tcp_cc_fastrecovery_clear (tcp_connection_t * tc);
 
 fib_node_index_t tcp_lookup_rmt_in_fib (tcp_connection_t * tc);
 
@@ -1035,6 +1027,12 @@ tcp_cc_rcv_cong_ack (tcp_connection_t * tc, tcp_cc_ack_t ack_type,
   tc->cc_algo->rcv_cong_ack (tc, ack_type, rs);
 }
 
+static inline void
+tcp_cc_congestion (tcp_connection_t * tc)
+{
+  tc->cc_algo->congestion (tc);
+}
+
 static inline void
 tcp_cc_loss (tcp_connection_t * tc)
 {
@@ -1068,9 +1066,10 @@ tcp_cc_get_pacing_rate (tcp_connection_t * tc)
     return tc->cc_algo->get_pacing_rate (tc);
 
   f64 srtt = clib_min ((f64) tc->srtt * TCP_TICK, tc->mrtt_us);
+
   /* TODO should constrain to interface's max throughput but
    * we don't have link speeds for sw ifs ..*/
-  return (tc->cwnd / srtt);
+  return ((f64) tc->cwnd / srtt);
 }
 
 always_inline void
@@ -1235,6 +1234,8 @@ vlib_buffer_push_tcp_net_order (vlib_buffer_t * b, u16 sp, u16 dp, u32 seq,
   th->window = wnd;
   th->checksum = 0;
   th->urgent_pointer = 0;
+  vnet_buffer (b)->l4_hdr_offset = (u8 *) th - b->data;
+  b->flags |= VNET_BUFFER_F_L4_HDR_OFFSET_VALID;
   return th;
 }