From: Stefano Brivio <sbrivio@redhat.com>
To: passt-dev@passt.top
Subject: [PATCH 1/4] tcp: Fix ACK sequence on FIN to tap
Date: Thu, 2 Oct 2025 02:06:43 +0200 [thread overview]
Message-ID: <20251002000646.2136202-2-sbrivio@redhat.com> (raw)
In-Reply-To: <20251002000646.2136202-1-sbrivio@redhat.com>
If we reach end-of-file on a socket (or get EPOLLRDHUP / EPOLLHUP) and
send a FIN segment to the guest / container acknowledging a sequence
number that's behind what we received so far, we won't have any
further trigger to send an updated ACK segment, as we are now
switching the epoll socket monitoring to edge-triggered mode.
To avoid this situation, in tcp_update_seqack_wnd(), we set the next
acknowledgement sequence to the current observed sequence, regardless
of what was acknowledged socket-side.
However, we don't necessarily call tcp_update_seqack_wnd() before
sending the FIN segment, which might potentially lead to a situation,
not observed in practice, where we unnecessarily cause a
retransmission at some point after our FIN segment.
Avoid that by setting the ACK sequence to whatever we received from
the container / guest, before sending a FIN segment and switching to
EPOLLET.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
tcp_buf.c | 14 +++++++++++++-
tcp_vu.c | 7 ++++++-
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/tcp_buf.c b/tcp_buf.c
index a493b5a..cc106bc 100644
--- a/tcp_buf.c
+++ b/tcp_buf.c
@@ -368,7 +368,19 @@ int tcp_buf_data_from_sock(const struct ctx *c, struct tcp_tap_conn *conn)
conn_flag(c, conn, STALLED);
} else if ((conn->events & (SOCK_FIN_RCVD | TAP_FIN_SENT)) ==
SOCK_FIN_RCVD) {
- int ret = tcp_buf_send_flag(c, conn, FIN | ACK);
+ int ret;
+
+ /* On TAP_FIN_SENT, we won't get further data events
+ * from the socket, and this might be the last ACK
+ * segment we send to the tap, so update its sequence to
+ * include everything we received until now.
+ *
+ * See also the special handling on CONN_IS_CLOSING() in
+ * tcp_update_seqack_wnd().
+ */
+ conn->seq_ack_to_tap = conn->seq_from_tap;
+
+ ret = tcp_buf_send_flag(c, conn, FIN | ACK);
if (ret) {
tcp_rst(c, conn);
return ret;
diff --git a/tcp_vu.c b/tcp_vu.c
index ebd3a1e..3ec3538 100644
--- a/tcp_vu.c
+++ b/tcp_vu.c
@@ -410,7 +410,12 @@ int tcp_vu_data_from_sock(const struct ctx *c, struct tcp_tap_conn *conn)
conn_flag(c, conn, STALLED);
} else if ((conn->events & (SOCK_FIN_RCVD | TAP_FIN_SENT)) ==
SOCK_FIN_RCVD) {
- int ret = tcp_vu_send_flag(c, conn, FIN | ACK);
+ int ret;
+
+ /* See tcp_buf_data_from_sock() */
+ conn->seq_ack_to_tap = conn->seq_from_tap;
+
+ ret = tcp_vu_send_flag(c, conn, FIN | ACK);
if (ret) {
tcp_rst(c, conn);
return ret;
--
2.43.0
next prev parent reply other threads:[~2025-10-02 0:06 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-02 0:06 [PATCH 0/4] tcp: Fix bad switch to CLOSE-WAIT state and surrounding issues Stefano Brivio
2025-10-02 0:06 ` Stefano Brivio [this message]
2025-10-02 2:41 ` [PATCH 1/4] tcp: Fix ACK sequence on FIN to tap David Gibson
2025-10-02 11:58 ` Stefano Brivio
2025-10-03 3:19 ` David Gibson
2025-10-06 22:32 ` Stefano Brivio
2025-10-06 23:31 ` David Gibson
2025-10-02 0:06 ` [PATCH 2/4] tcp: Completely ignore data segment in CLOSE-WAIT state, log a message Stefano Brivio
2025-10-02 2:44 ` David Gibson
2025-10-02 0:06 ` [PATCH 3/4] tcp: Don't consider FIN flags with mismatching sequence Stefano Brivio
2025-10-02 2:52 ` David Gibson
2025-10-02 3:02 ` David Gibson
2025-10-02 11:51 ` Stefano Brivio
2025-10-03 3:43 ` David Gibson
2025-10-06 22:32 ` Stefano Brivio
2025-10-06 23:34 ` David Gibson
2025-10-02 0:06 ` [PATCH 4/4] tcp: On partial send (incomplete sendmsg()), request a retransmission right away Stefano Brivio
2025-10-02 3:00 ` David Gibson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251002000646.2136202-2-sbrivio@redhat.com \
--to=sbrivio@redhat.com \
--cc=passt-dev@passt.top \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).