tcp_update_rcv_wnd (tc);
- if (tc->flags & TCP_CONN_RATE_SAMPLE)
+ if (tc->cfg_flags & TCP_CFG_F_RATE_SAMPLE)
tc->flags |= TCP_CONN_TRACK_BURST;
if (tc->snd_una == tc->snd_nxt)
tcp_compute_checksum (tcp_connection_t * tc, vlib_buffer_t * b)
{
u16 checksum = 0;
- if (PREDICT_FALSE (tc->flags & TCP_CONN_NO_CSUM_OFFLOAD))
+ if (PREDICT_FALSE (tc->cfg_flags & TCP_CFG_F_NO_CSUM_OFFLOAD))
{
tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
vlib_main_t *vm = wrk->vm;
return checksum;
}
-
/**
* Prepare ACK
*/
ASSERT ((pkt_ih4->ip_version_and_header_length & 0xF0) == 0x40);
ih4 = vlib_buffer_push_ip4 (vm, b, &pkt_ih4->dst_address,
&pkt_ih4->src_address, IP_PROTOCOL_TCP,
- (!(tc->flags & TCP_CONN_NO_CSUM_OFFLOAD)));
+ tcp_csum_offload (tc));
th->checksum = ip4_tcp_udp_compute_checksum (vm, b, ih4);
}
else
ip4_header_t *ih;
ih = vlib_buffer_push_ip4 (vm, b, &tc->c_lcl_ip4,
&tc->c_rmt_ip4, IP_PROTOCOL_TCP,
- (!(tc->flags & TCP_CONN_NO_CSUM_OFFLOAD)));
+ tcp_csum_offload (tc));
th->checksum = ip4_tcp_udp_compute_checksum (vm, b, ih);
}
else
return;
}
+ /* If we have non-dupacks programmed, no need to send them */
+ if ((tc->flags & TCP_CONN_SNDACK) && !tc->pending_dupacks)
+ tc->flags &= ~TCP_CONN_SNDACK;
+
tcp_retransmit_timer_force_update (tc);
b = vlib_get_buffer (vm, bi);
tcp_init_buffer (vm, b);
tc->bytes_out += data_len;
tc->data_segs_out += 1;
-
th->checksum = tcp_compute_checksum (tc, b);
TCP_EVT (TCP_EVT_PKTIZE, tc);
tc->snd_rxt_bytes += n_bytes;
- if (tc->flags & TCP_CONN_RATE_SAMPLE)
+ if (tc->cfg_flags & TCP_CFG_F_RATE_SAMPLE)
tcp_bt_track_rxt (tc, start, start + n_bytes);
tc->bytes_retrans += n_bytes;
|| tc->snd_nxt == tc->snd_una_max
|| tc->rto_boff > 1));
- if (tc->flags & TCP_CONN_RATE_SAMPLE)
+ if (tc->cfg_flags & TCP_CFG_F_RATE_SAMPLE)
{
tcp_bt_check_app_limited (tc);
tcp_bt_track_tx (tc);
return (tx_adv_sack > (tc->snd_una - tc->prr_start) * rr);
}
+static inline u8
+tcp_max_tx_deq (tcp_connection_t * tc)
+{
+ return (transport_max_tx_dequeue (&tc->connection)
+ - (tc->snd_nxt - tc->snd_una));
+}
+
#define scoreboard_rescue_rxt_valid(_sb, _tc) \
(seq_geq (_sb->rescue_rxt, _tc->snd_una) \
&& seq_leq (_sb->rescue_rxt, _tc->snd_congestion))
sb = &tc->sack_sb;
/* Check if snd_una is a lost retransmit */
- if (seq_gt (sb->high_sacked, tc->snd_congestion)
+ if (pool_elts (sb->holes)
+ && seq_gt (sb->high_sacked, tc->snd_congestion)
&& tc->rxt_head != tc->snd_una
&& tcp_retransmit_should_retry_head (tc, sb))
{
if (!tc->pending_dupacks)
{
- tcp_send_ack (tc);
- return 1;
+ if (tcp_in_cong_recovery (tc) || !tcp_max_tx_deq (tc)
+ || tc->state != TCP_STATE_ESTABLISHED)
+ {
+ tcp_send_ack (tc);
+ return 1;
+ }
+ return 0;
}
/* If we're supposed to send dupacks but have no ooo data
if (!vec_len (tc->snd_sacks))
{
tcp_send_ack (tc);
+ tc->pending_dupacks = 0;
return 1;
}
if (is_ip4)
ih0 = vlib_buffer_push_ip4 (vm, b0, &tc0->c_lcl_ip4, &tc0->c_rmt_ip4,
- IP_PROTOCOL_TCP,
- (!(tc0->flags & TCP_CONN_NO_CSUM_OFFLOAD)));
+ IP_PROTOCOL_TCP, tcp_csum_offload (tc0));
else
ih0 = vlib_buffer_push_ip6 (vm, b0, &tc0->c_lcl_ip6, &tc0->c_rmt_ip6,
IP_PROTOCOL_TCP);
always_inline void
tcp_check_if_gso (tcp_connection_t * tc, vlib_buffer_t * b)
{
- if (!tc->is_tso)
+ if (PREDICT_TRUE (!(tc->cfg_flags & TCP_CFG_F_TSO)))
return;
+
u16 data_len = b->current_length - sizeof (tcp_header_t) - tc->snd_opts_len;
if (PREDICT_FALSE (b->flags & VLIB_BUFFER_TOTAL_LENGTH_VALID))