}
static void
-tcp_cc_update (tcp_connection_t * tc, vlib_buffer_t * b)
+tcp_cc_update (tcp_connection_t * tc, tcp_rate_sample_t * rs)
{
ASSERT (!tcp_in_cong_recovery (tc) || tcp_is_lost_fin (tc));
/* Congestion avoidance */
- tcp_cc_rcv_ack (tc);
+ tcp_cc_rcv_ack (tc, rs);
/* If a cumulative ack, make sure dupacks is 0 */
tc->rcv_dupacks = 0;
* One function to rule them all ... and in the darkness bind them
*/
static void
-tcp_cc_handle_event (tcp_connection_t * tc, u32 is_dack)
+tcp_cc_handle_event (tcp_connection_t * tc, tcp_rate_sample_t * rs,
+ u32 is_dack)
{
u32 rxt_delivered;
if (tc->rcv_dupacks > TCP_DUPACK_THRESHOLD && !tc->bytes_acked)
{
ASSERT (tcp_in_fastrecovery (tc));
- tc->cc_algo->rcv_cong_ack (tc, TCP_CC_DUPACK);
+ tcp_cc_rcv_cong_ack (tc, TCP_CC_DUPACK, rs);
return;
}
else if (tcp_should_fastrecover (tc))
}
tcp_cc_init_congestion (tc);
- tc->cc_algo->rcv_cong_ack (tc, TCP_CC_DUPACK);
+ tcp_cc_rcv_cong_ack (tc, TCP_CC_DUPACK, rs);
if (tcp_opts_sack_permitted (&tc->rcv_opts))
{
else if (!tc->bytes_acked
|| (tc->bytes_acked && !tcp_in_cong_recovery (tc)))
{
- tc->cc_algo->rcv_cong_ack (tc, TCP_CC_DUPACK);
+ tcp_cc_rcv_cong_ack (tc, TCP_CC_DUPACK, rs);
return;
}
else
}
/* Treat as congestion avoidance ack */
- tcp_cc_rcv_ack (tc);
+ tcp_cc_rcv_ack (tc, rs);
return;
}
/* Post RTO timeout don't try anything fancy */
if (tcp_in_recovery (tc))
{
- tcp_cc_rcv_ack (tc);
+ tcp_cc_rcv_ack (tc, rs);
transport_add_tx_event (&tc->connection);
return;
}
tc->snd_rxt_bytes = 0;
}
- tc->cc_algo->rcv_cong_ack (tc, TCP_CC_PARTIALACK);
+ tcp_cc_rcv_cong_ack (tc, TCP_CC_PARTIALACK, rs);
/*
* Since this was a partial ack, try to retransmit some more data
tcp_header_t * th, u32 * error)
{
u32 prev_snd_wnd, prev_snd_una;
+ tcp_rate_sample_t rs = { 0 };
u8 is_dack;
TCP_EVT_DBG (TCP_EVT_CC_STAT, tc);
TCP_EVT_DBG (TCP_EVT_ACK_RCV_ERR, tc, 1,
vnet_buffer (b)->tcp.ack_number);
if (tcp_in_fastrecovery (tc) && tc->rcv_dupacks == TCP_DUPACK_THRESHOLD)
- tcp_cc_handle_event (tc, 1);
+ tcp_cc_handle_event (tc, 0, 1);
/* Don't drop yet */
return 0;
}
tcp_update_rtt (tc, vnet_buffer (b)->tcp.ack_number);
}
+ if (tc->flags & TCP_CONN_RATE_SAMPLE)
+ tcp_bt_sample_delivery_rate (tc, &rs);
+
TCP_EVT_DBG (TCP_EVT_ACK_RCVD, tc);
/*
if (tcp_ack_is_cc_event (tc, b, prev_snd_wnd, prev_snd_una, &is_dack))
{
- tcp_cc_handle_event (tc, is_dack);
+ tcp_cc_handle_event (tc, &rs, is_dack);
if (!tcp_in_cong_recovery (tc))
{
*error = TCP_ERROR_ACK_OK;
/*
* Update congestion control (slow start/congestion avoidance)
*/
- tcp_cc_update (tc, b);
+ tcp_cc_update (tc, &rs);
*error = TCP_ERROR_ACK_OK;
return 0;
}