54476b
From 7146bbf518d4b390a2839b3d0e47ef2116d4915d Mon Sep 17 00:00:00 2001
54476b
From: Jakub Kicinski <kuba@kernel.org>
54476b
Date: Wed, 2 Feb 2022 09:38:24 -0800
54476b
Subject: [PATCH] Report number of reorder_seen
54476b
54476b
TCP can detect reordering by tracking SACKs and timestamps
54476b
coming back to the sender. This is useful information for
54476b
investigating performance issues and testing networks as
54476b
good networks should generally not reorder packets.
54476b
---
54476b
 src/iperf.h     |  2 ++
54476b
 src/iperf_api.c |  6 ++++--
54476b
 src/iperf_api.h |  1 +
54476b
 src/tcp_info.c  | 14 ++++++++++++++
54476b
 4 files changed, 21 insertions(+), 2 deletions(-)
54476b
54476b
diff --git a/src/iperf.h b/src/iperf.h
54476b
index 6de234325..2d280e7ee 100644
54476b
--- a/src/iperf.h
54476b
+++ b/src/iperf.h
54476b
@@ -110,6 +110,7 @@ struct iperf_interval_results
54476b
     int rtt;
54476b
     int rttvar;
54476b
     int pmtu;
54476b
+    int reorder;
54476b
 };
54476b
 
54476b
 struct iperf_stream_result
54476b
@@ -121,6 +122,7 @@ struct iperf_stream_result
54476b
     iperf_size_t bytes_sent_omit;
54476b
     int stream_prev_total_retrans;
54476b
     int stream_retrans;
54476b
+    int stream_reorder;
54476b
     int stream_prev_total_sacks;
54476b
     int stream_sacks;
54476b
     int stream_max_rtt;
54476b
diff --git a/src/iperf_api.c b/src/iperf_api.c
54476b
index 7462f823c..af0c6827f 100644
54476b
--- a/src/iperf_api.c
54476b
+++ b/src/iperf_api.c
54476b
@@ -3185,6 +3185,8 @@ iperf_stats_callback(struct iperf_test *test)
54476b
 
54476b
 		    temp.rttvar = get_rttvar(&temp);
54476b
 		    temp.pmtu = get_pmtu(&temp);
54476b
+		    temp.reorder = get_reorder(&temp);
54476b
+		    rp->stream_reorder = temp.reorder;
54476b
 		}
54476b
 	    }
54476b
 	} else {
54476b
@@ -3623,7 +3625,7 @@ iperf_print_results(struct iperf_test *test)
54476b
                     if (test->sender_has_retransmits) {
54476b
                         /* Sender summary, TCP and SCTP with retransmits. */
54476b
                         if (test->json_output)
54476b
-                            cJSON_AddItemToObject(json_summary_stream, "sender", iperf_json_printf("socket: %d  start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  retransmits: %d  max_snd_cwnd:  %d  max_snd_wnd:  %d  max_rtt:  %d  min_rtt:  %d  mean_rtt:  %d sender: %b", (int64_t) sp->socket, (double) start_time, (double) sender_time, (double) sender_time, (int64_t) bytes_sent, bandwidth * 8, (int64_t) sp->result->stream_retrans, (int64_t) sp->result->stream_max_snd_cwnd, (int64_t) sp->result->stream_max_snd_wnd, (int64_t) sp->result->stream_max_rtt, (int64_t) sp->result->stream_min_rtt, (int64_t) ((sp->result->stream_count_rtt == 0) ? 0 : sp->result->stream_sum_rtt / sp->result->stream_count_rtt), stream_must_be_sender));
54476b
+                            cJSON_AddItemToObject(json_summary_stream, "sender", iperf_json_printf("socket: %d  start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  retransmits: %d  reorder:  %d  max_snd_cwnd:  %d  max_snd_wnd:  %d  max_rtt:  %d  min_rtt:  %d  mean_rtt:  %d sender: %b", (int64_t) sp->socket, (double) start_time, (double) sender_time, (double) sender_time, (int64_t) bytes_sent, bandwidth * 8, (int64_t) sp->result->stream_retrans, (int64_t) sp->result->stream_reorder, (int64_t) sp->result->stream_max_snd_cwnd, (int64_t) sp->result->stream_max_snd_wnd, (int64_t) sp->result->stream_max_rtt, (int64_t) sp->result->stream_min_rtt, (int64_t) ((sp->result->stream_count_rtt == 0) ? 0 : sp->result->stream_sum_rtt / sp->result->stream_count_rtt), stream_must_be_sender));
54476b
                         else
54476b
                             if (test->role == 's' && !sp->sender) {
54476b
                                 if (test->verbose)
54476b
@@ -4070,7 +4072,7 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
54476b
 	if (test->sender_has_retransmits == 1 && sp->sender) {
54476b
 	    /* Interval, TCP with retransmits. */
54476b
 	    if (test->json_output)
54476b
-		cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d  start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  retransmits: %d  snd_cwnd:  %d  snd_wnd:  %d  rtt:  %d  rttvar: %d  pmtu: %d  omitted: %b sender: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, (int64_t) irp->interval_retrans, (int64_t) irp->snd_cwnd, (int64_t) irp->snd_wnd, (int64_t) irp->rtt, (int64_t) irp->rttvar, (int64_t) irp->pmtu, irp->omitted, sp->sender));
54476b
+		cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d  start: %f  end: %f  seconds: %f  bytes: %d  bits_per_second: %f  retransmits: %d  snd_cwnd:  %d  snd_wnd:  %d  rtt:  %d  rttvar: %d  pmtu: %d  reorder: %d  omitted: %b sender: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, (int64_t) irp->interval_retrans, (int64_t) irp->snd_cwnd, (int64_t) irp->snd_wnd, (int64_t) irp->rtt, (int64_t) irp->rttvar, (int64_t) irp->pmtu, (int64_t) irp->reorder, irp->omitted, sp->sender));
54476b
 	    else {
54476b
 		unit_snprintf(cbuf, UNIT_LEN, irp->snd_cwnd, 'A');
54476b
 		iperf_printf(test, report_bw_retrans_cwnd_format, sp->socket, mbuf, st, et, ubuf, nbuf, irp->interval_retrans, cbuf, irp->omitted?report_omitted:"");
54476b
diff --git a/src/iperf_api.h b/src/iperf_api.h
54476b
index b8da94d1e..84bc249c4 100644
54476b
--- a/src/iperf_api.h
54476b
+++ b/src/iperf_api.h
54476b
@@ -285,6 +285,7 @@ long get_snd_wnd(struct iperf_interval_results *irp);
54476b
 long get_rtt(struct iperf_interval_results *irp);
54476b
 long get_rttvar(struct iperf_interval_results *irp);
54476b
 long get_pmtu(struct iperf_interval_results *irp);
54476b
+long get_reorder(struct iperf_interval_results *irp);
54476b
 void print_tcpinfo(struct iperf_test *test);
54476b
 void build_tcpinfo_message(struct iperf_interval_results *r, char *message);
54476b
 
54476b
diff --git a/src/tcp_info.c b/src/tcp_info.c
54476b
index 6b75384d4..1c6734d4f 100644
54476b
--- a/src/tcp_info.c
54476b
+++ b/src/tcp_info.c
54476b
@@ -213,6 +213,20 @@ get_pmtu(struct iperf_interval_results *irp)
54476b
 #endif
54476b
 }
54476b
 
54476b
+/*************************************************************/
54476b
+/*
54476b
+ * Return number of reordering events seen.
54476b
+ */
54476b
+long
54476b
+get_reorder(struct iperf_interval_results *irp)
54476b
+{
54476b
+#if defined(linux) && defined(TCP_REPAIR_ON)
54476b
+    return irp->tcpInfo.tcpi_reord_seen;
54476b
+#else
54476b
+    return -1;
54476b
+#endif
54476b
+}
54476b
+
54476b
 /*************************************************************/
54476b
 void
54476b
 build_tcpinfo_message(struct iperf_interval_results *r, char *message)