aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2020-01-08 22:01:54 +0000
committerFlorin Coras <florin.coras@gmail.com>2020-01-14 23:38:05 +0000
commitc95eefb393d05167ce6e35e5617179f536de0bda (patch)
treee7a58d10e10d12b26718af5dc903d1f82fce0bcb
parent48bdbcd8f9d573138c43f994ddfff946d8a9d9b5 (diff)
tcp: handle ack advancement with no holes and reneging
Type: fix Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I9afba8dc9e087b8c436fe568531c02614a577a7c
-rw-r--r--src/plugins/unittest/tcp_test.c36
-rwxr-xr-xsrc/vnet/tcp/tcp_input.c2
2 files changed, 36 insertions, 2 deletions
diff --git a/src/plugins/unittest/tcp_test.c b/src/plugins/unittest/tcp_test.c
index 777e17352f7..bdd74c8bc0a 100644
--- a/src/plugins/unittest/tcp_test.c
+++ b/src/plugins/unittest/tcp_test.c
@@ -262,11 +262,44 @@ tcp_test_sack_rx (vlib_main_t * vm, unformat_input_t * input)
sb->rxt_sacked);
/*
- * Sack all up to 1000
+ * Sack remaining bytes [990 1000]
*/
+ tc->rcv_opts.sacks[0].start = 990;
+ tc->rcv_opts.sacks[0].end = 1000;
+
+ tcp_rcv_sacks (tc, 960);
+
+ TCP_TEST ((sb->is_reneging), "is reneging");
+ TCP_TEST ((sb->sacked_bytes == 40), "sacked bytes %d", sb->sacked_bytes);
+ TCP_TEST ((sb->last_sacked_bytes == 10),
+ "last sacked bytes %d", sb->last_sacked_bytes);
+ TCP_TEST ((sb->rxt_sacked == 0), "last rxt sacked bytes %d",
+ sb->rxt_sacked);
+ TCP_TEST (pool_elts (sb->holes) == 0, "no holes left");
+
+ /*
+ * Ack up to 970 no sack blocks
+ */
+ vec_reset_length (tc->rcv_opts.sacks);
+ tc->rcv_opts.flags &= ~TCP_OPTS_FLAG_SACK;
+ tcp_rcv_sacks (tc, 970);
+
+ TCP_TEST ((sb->is_reneging), "is reneging");
+ TCP_TEST ((sb->sacked_bytes == 30), "sacked bytes %d", sb->sacked_bytes);
+ TCP_TEST ((sb->last_sacked_bytes == 0),
+ "last sacked bytes %d", sb->last_sacked_bytes);
+ TCP_TEST ((sb->rxt_sacked == 0), "last rxt sacked bytes %d",
+ sb->rxt_sacked);
+
+ /*
+ * Ack all up to 1000
+ */
+ tc->snd_una = 970;
tcp_rcv_sacks (tc, 1000);
TCP_TEST ((sb->high_sacked == 1000), "max sacked byte %u", sb->high_sacked);
TCP_TEST ((sb->sacked_bytes == 0), "sacked bytes %d", sb->sacked_bytes);
+ TCP_TEST (sb->last_bytes_delivered == 30, "last bytes delivered %d",
+ sb->last_bytes_delivered);
TCP_TEST ((sb->last_sacked_bytes == 0),
"last sacked bytes %d", sb->last_sacked_bytes);
TCP_TEST ((sb->lost_bytes == 0), "lost bytes %u", sb->lost_bytes);
@@ -276,6 +309,7 @@ tcp_test_sack_rx (vlib_main_t * vm, unformat_input_t * input)
* Add new block
*/
tc->flags = 0;
+ tc->rcv_opts.flags |= TCP_OPTS_FLAG_SACK;
vec_reset_length (tc->rcv_opts.sacks);
block.start = 1200;
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c
index 080d8a99bc4..cb5020d118e 100755
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -990,7 +990,7 @@ tcp_rcv_sacks (tcp_connection_t * tc, u32 ack)
sb->last_bytes_delivered = 0;
sb->rxt_sacked = 0;
- if (!tcp_opts_sack (&tc->rcv_opts)
+ if (!tcp_opts_sack (&tc->rcv_opts) && !sb->sacked_bytes
&& sb->head == TCP_INVALID_SACK_HOLE_INDEX)
return;