aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/tcp_sack.c6
-rw-r--r--sys/netinet/tcp_stacks/bbr.c4
-rw-r--r--sys/netinet/tcp_stacks/rack.c14
-rw-r--r--sys/netinet/tcp_subr.c27
-rw-r--r--sys/netinet/tcp_var.h16
5 files changed, 57 insertions, 10 deletions
diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c
index 9753536926d5..25eb633fbbd4 100644
--- a/sys/netinet/tcp_sack.c
+++ b/sys/netinet/tcp_sack.c
@@ -604,6 +604,12 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
SEQ_GT(sack.end, tp->snd_una) &&
SEQ_LEQ(sack.end, tp->snd_max)) {
sack_blocks[num_sack_blks++] = sack;
+ } else if (SEQ_LEQ(sack.start, th_ack) &&
+ SEQ_LEQ(sack.end, th_ack)) {
+ /*
+ * Its a D-SACK block.
+ */
+ tcp_record_dsack(tp, sack.start, sack.end, 0);
}
}
}
diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c
index c96fec07b6c9..3c4cf0f54d97 100644
--- a/sys/netinet/tcp_stacks/bbr.c
+++ b/sys/netinet/tcp_stacks/bbr.c
@@ -7593,14 +7593,12 @@ proc_sack:
}
sack_blocks[num_sack_blks] = sack;
num_sack_blks++;
-#ifdef NETFLIX_STATS
} else if (SEQ_LEQ(sack.start, th_ack) &&
SEQ_LEQ(sack.end, th_ack)) {
/*
* Its a D-SACK block.
*/
- tcp_record_dsack(sack.start, sack.end);
-#endif
+ tcp_record_dsack(tp, sack.start, sack.end, 0);
}
}
if (num_sack_blks == 0)
diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
index 2369a1c368bf..00f830caf217 100644
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -9402,11 +9402,12 @@ rack_do_detection(struct tcpcb *tp, struct tcp_rack *rack, uint32_t bytes_this_
}
#endif
-static void
+static int
rack_note_dsack(struct tcp_rack *rack, tcp_seq start, tcp_seq end)
{
uint32_t am, l_end;
+ int was_tlp = 0;
if (SEQ_GT(end, start))
am = end - start;
@@ -9422,6 +9423,7 @@ rack_note_dsack(struct tcp_rack *rack, tcp_seq start, tcp_seq end)
* our previous retransmit TLP.
*/
rack_log_dsack_event(rack, 7, __LINE__, start, end);
+ was_tlp = 1;
goto skip_dsack_round;
}
if (rack->rc_last_sent_tlp_seq_valid) {
@@ -9433,6 +9435,7 @@ rack_note_dsack(struct tcp_rack *rack, tcp_seq start, tcp_seq end)
* for reordering purposes.
*/
rack_log_dsack_event(rack, 7, __LINE__, start, end);
+ was_tlp = 1;
goto skip_dsack_round;
}
}
@@ -9462,6 +9465,7 @@ skip_dsack_round:
rack->r_ctl.retran_during_recovery = 0;
rack->r_ctl.dsack_byte_cnt = 0;
}
+ return (was_tlp);
}
static void
@@ -9614,13 +9618,13 @@ rack_log_ack(struct tcpcb *tp, struct tcpopt *to, struct tcphdr *th, int entered
num_sack_blks++;
} else if (SEQ_LEQ(sack.start, th_ack) &&
SEQ_LEQ(sack.end, th_ack)) {
-#ifdef NETFLIX_STATS
+ int was_tlp;
+
+ was_tlp = rack_note_dsack(rack, sack.start, sack.end);
/*
* Its a D-SACK block.
*/
- tcp_record_dsack(sack.start, sack.end);
-#endif
- rack_note_dsack(rack, sack.start, sack.end);
+ tcp_record_dsack(tp, sack.start, sack.end, was_tlp);
}
}
if (rack->rc_dsack_round_seen) {
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 697ae7d3270b..9d66086a383b 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -390,6 +390,30 @@ static int tcp_fb_cnt = 0;
struct tcp_funchead t_functions;
static struct tcp_function_block *tcp_func_set_ptr = &tcp_def_funcblk;
+void
+tcp_record_dsack(struct tcpcb *tp, tcp_seq start, tcp_seq end, int tlp)
+{
+ TCPSTAT_INC(tcps_dsack_count);
+ tp->t_dsack_pack++;
+ if (tlp == 0) {
+ if (SEQ_GT(end, start)) {
+ tp->t_dsack_bytes += (end - start);
+ TCPSTAT_ADD(tcps_dsack_bytes, (end - start));
+ } else {
+ tp->t_dsack_tlp_bytes += (start - end);
+ TCPSTAT_ADD(tcps_dsack_bytes, (start - end));
+ }
+ } else {
+ if (SEQ_GT(end, start)) {
+ tp->t_dsack_bytes += (end - start);
+ TCPSTAT_ADD(tcps_dsack_tlp_bytes, (end - start));
+ } else {
+ tp->t_dsack_tlp_bytes += (start - end);
+ TCPSTAT_ADD(tcps_dsack_tlp_bytes, (start - end));
+ }
+ }
+}
+
static struct tcp_function_block *
find_tcp_functions_locked(struct tcp_function_set *fs)
{
@@ -4003,6 +4027,9 @@ tcp_inptoxtp(const struct inpcb *inp, struct xtcpcb *xt)
xt->t_snd_wnd = tp->snd_wnd;
xt->t_snd_cwnd = tp->snd_cwnd;
xt->t_snd_ssthresh = tp->snd_ssthresh;
+ xt->t_dsack_bytes = tp->t_dsack_bytes;
+ xt->t_dsack_tlp_bytes = tp->t_dsack_tlp_bytes;
+ xt->t_dsack_pack = tp->t_dsack_pack;
xt->t_maxseg = tp->t_maxseg;
xt->xt_ecn = (tp->t_flags2 & TF2_ECN_PERMIT) ? 1 : 0 +
(tp->t_flags2 & TF2_ACE_PERMIT) ? 2 : 0;
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index c26f503f4a1d..d5b2963ef4dc 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -265,6 +265,9 @@ struct tcpcb {
uint64_t t_sndtlpbyte; /* total tail loss probe bytes sent */
uint64_t t_sndbytes; /* total bytes sent */
uint64_t t_snd_rxt_bytes; /* total bytes retransmitted */
+ uint32_t t_dsack_bytes; /* Total number of dsack bytes we have received */
+ uint32_t t_dsack_tlp_bytes; /* Total number of dsack bytes we have received for TLPs sent */
+ uint32_t t_dsack_pack; /* Total dsack packets we have recieved */
uint8_t t_tfo_client_cookie_len; /* TCP Fast Open client cookie length */
uint32_t t_end_info_status; /* Status flag of end info */
@@ -703,7 +706,12 @@ struct tcpstat {
uint64_t tcps_tunneled_pkts; /* Packets encap's in UDP received */
uint64_t tcps_tunneled_errs; /* Packets that had errors that were UDP encaped */
- uint64_t _pad[9]; /* 6 UTO, 3 TBD */
+ /* Dsack related stats */
+ uint64_t tcps_dsack_count; /* Number of ACKs arriving with DSACKs */
+ uint64_t tcps_dsack_bytes; /* Number of bytes DSACK'ed no TLP */
+ uint64_t tcps_dsack_tlp_bytes; /* Number of bytes DSACK'ed due to TLPs */
+
+ uint64_t _pad[6]; /* 3 UTO, 3 TBD */
};
#define tcps_rcvmemdrop tcps_rcvreassfull /* compat */
@@ -801,9 +809,12 @@ struct xtcpcb {
uint32_t t_rcv_wnd; /* (s) */
uint32_t t_snd_wnd; /* (s) */
uint32_t xt_ecn; /* (s) */
+ uint32_t t_dsack_bytes; /* (n) */
+ uint32_t t_dsack_tlp_bytes; /* (n) */
+ uint32_t t_dsack_pack; /* (n) */
uint16_t xt_encaps_port; /* (s) */
int16_t spare16;
- int32_t spare32[25];
+ int32_t spare32[22];
} __aligned(8);
#ifdef _KERNEL
@@ -1064,6 +1075,7 @@ int tcp_twcheck(struct inpcb *, struct tcpopt *, struct tcphdr *,
struct mbuf *, int);
void tcp_setpersist(struct tcpcb *);
void tcp_slowtimo(void);
+void tcp_record_dsack(struct tcpcb *tp, tcp_seq start, tcp_seq end, int tlp);
struct tcptemp *
tcpip_maketemplate(struct inpcb *);
void tcpip_fillheaders(struct inpcb *, uint16_t, void *, void *);