_(FAST_RECOVERY, "Fast Recovery") \
_(FR_1_SMSS, "Sent 1 SMSS") \
_(HALF_OPEN_DONE, "Half-open completed") \
- _(FINPNDG, "FIN pending")
+ _(FINPNDG, "FIN pending") \
typedef enum _tcp_connection_flag_bits
{
/* Congestion control */
u32 cwnd; /**< Congestion window */
+ u32 cwnd_acc_bytes; /**< Bytes accumulated for cwnd increment */
u32 ssthresh; /**< Slow-start threshold */
u32 prev_ssthresh; /**< ssthresh before congestion */
u32 prev_cwnd; /**< ssthresh before congestion */
u16 mss; /**< Our max seg size that includes options */
u32 limited_transmit; /**< snd_nxt when limited transmit starts */
u32 last_fib_check; /**< Last time we checked fib route for peer */
+ u32 sw_if_index; /**< Interface for the connection */
} tcp_connection_t;
struct _tcp_cc_algorithm
u8 next, error;
} tcp_lookup_dispatch_t;
+typedef struct tcp_worker_ctx_
+{
+ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
+ u32 time_now; /**< worker time */
+ tw_timer_wheel_16t_2w_512sl_t timer_wheel; /**< worker timer wheel */
+ u32 *tx_buffers; /**< tx buffer free list */
+ vlib_frame_t *tx_frames[2]; /**< tx frames for tcp 4/6
+ output nodes */
+ vlib_frame_t *ip_lookup_tx_frames[2]; /**< tx frames for ip 4/6
+ lookup nodes */
+} tcp_worker_ctx_t;
+
typedef struct _tcp_main
{
/* Per-worker thread tcp connection pools */
u8 log2_tstamp_clocks_per_tick;
f64 tstamp_ticks_per_clock;
- u32 *time_now;
-
- /** per-worker tx buffer free lists */
- u32 **tx_buffers;
- /** per-worker tx frames to tcp 4/6 output nodes */
- vlib_frame_t **tx_frames[2];
- /** per-worker tx frames to ip 4/6 lookup nodes */
- vlib_frame_t **ip_lookup_tx_frames[2];
- /* Per worker-thread timer wheel for connections timers */
- tw_timer_wheel_16t_2w_512sl_t *timer_wheels;
+ /** per-worker context */
+ tcp_worker_ctx_t *wrk_ctx;
/* Pool of half-open connections on which we've sent a SYN */
tcp_connection_t *half_open_connections;
* Estimate of how many bytes we can still push into the network
*/
always_inline u32
-tcp_available_snd_space (const tcp_connection_t * tc)
+tcp_available_cc_snd_space (const tcp_connection_t * tc)
{
u32 available_wnd = tcp_available_snd_wnd (tc);
u32 flight_size = tcp_flight_size (tc);
/* Made public for unit testing only */
void tcp_update_sack_list (tcp_connection_t * tc, u32 start, u32 end);
+u32 tcp_sack_list_bytes (tcp_connection_t * tc);
always_inline u32
tcp_time_now (void)
{
- return tcp_main.time_now[vlib_get_thread_index ()];
+ return tcp_main.wrk_ctx[vlib_get_thread_index ()].time_now;
}
always_inline u32
tcp_set_time_now (u32 thread_index)
{
- tcp_main.time_now[thread_index] = clib_cpu_time_now ()
+ tcp_main.wrk_ctx[thread_index].time_now = clib_cpu_time_now ()
* tcp_main.tstamp_ticks_per_clock;
- return tcp_main.time_now[thread_index];
+ return tcp_main.wrk_ctx[thread_index].time_now;
}
-always_inline void
-tcp_update_time (f64 now, u32 thread_index)
-{
- tcp_set_time_now (thread_index);
- tw_timer_expire_timers_16t_2w_512sl (&tcp_main.timer_wheels[thread_index],
- now);
- tcp_flush_frames_to_output (thread_index);
-}
-
-u32 tcp_push_header (transport_connection_t * tconn, vlib_buffer_t * b);
+u32 tcp_session_push_header (transport_connection_t * tconn,
+ vlib_buffer_t * b);
u32
tcp_prepare_retransmit_segment (tcp_connection_t * tc, u32 offset,
{
ASSERT (tc->c_thread_index == vlib_get_thread_index ());
ASSERT (tc->timers[timer_id] == TCP_TIMER_HANDLE_INVALID);
- tc->timers[timer_id]
- = tw_timer_start_16t_2w_512sl (&tcp_main.timer_wheels[tc->c_thread_index],
- tc->c_c_index, timer_id, interval);
+ tc->timers[timer_id] =
+ tw_timer_start_16t_2w_512sl (&tcp_main.
+ wrk_ctx[tc->c_thread_index].timer_wheel,
+ tc->c_c_index, timer_id, interval);
}
always_inline void
if (tc->timers[timer_id] == TCP_TIMER_HANDLE_INVALID)
return;
- tw_timer_stop_16t_2w_512sl (&tcp_main.timer_wheels[tc->c_thread_index],
+ tw_timer_stop_16t_2w_512sl (&tcp_main.
+ wrk_ctx[tc->c_thread_index].timer_wheel,
tc->timers[timer_id]);
tc->timers[timer_id] = TCP_TIMER_HANDLE_INVALID;
}
{
ASSERT (tc->c_thread_index == vlib_get_thread_index ());
if (tc->timers[timer_id] != TCP_TIMER_HANDLE_INVALID)
- tw_timer_stop_16t_2w_512sl (&tcp_main.timer_wheels[tc->c_thread_index],
+ tw_timer_stop_16t_2w_512sl (&tcp_main.
+ wrk_ctx[tc->c_thread_index].timer_wheel,
tc->timers[timer_id]);
tc->timers[timer_id] =
- tw_timer_start_16t_2w_512sl (&tcp_main.timer_wheels[tc->c_thread_index],
+ tw_timer_start_16t_2w_512sl (&tcp_main.
+ wrk_ctx[tc->c_thread_index].timer_wheel,
tc->c_c_index, timer_id, interval);
}
#define tcp_validate_txf_size(_tc, _a) \
ASSERT(_tc->state != TCP_STATE_ESTABLISHED \
- || stream_session_tx_fifo_max_dequeue (&_tc->connection) >= _a)
+ || session_tx_fifo_max_dequeue (&_tc->connection) >= _a)
void
scoreboard_remove_hole (sack_scoreboard_t * sb,
sack_scoreboard_hole_t * hole);
-void scoreboard_update_lost (tcp_connection_t * tc, sack_scoreboard_t * sb);
sack_scoreboard_hole_t *scoreboard_insert_hole (sack_scoreboard_t * sb,
u32 prev_index, u32 start,
u32 end);