Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 Jan 2025 05:03:08 GMT
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 06bf119f265c - main - sockets/tcp: quick fix for regression with SO_REUSEPORT_LB
Message-ID:  <202501280503.50S5385J010919@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=06bf119f265c38c0ed16a1461fdc43356c3edf7a

commit 06bf119f265c38c0ed16a1461fdc43356c3edf7a
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-01-28 05:02:22 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-01-28 05:02:22 +0000

    sockets/tcp: quick fix for regression with SO_REUSEPORT_LB
    
    There was a long living problem that pr_listen is called every time on
    consecutive listen(2) syscalls.  Up until today it produces spurious TCP
    state change events in tracing software and other harmless problems.  But
    with 7cbb6b6e28db we started to call LIST_REMOVE() twice on the same
    entry.
    
    This is quite ugly, but quick and robust fix against regression, that we
    decided to put in the scope of the January stabilization week.  A better
    refactoring will happen later.
    
    Reviewed by:            markj
    Differential Revision:  https://reviews.freebsd.org/D48703
    Fixes:                  7cbb6b6e28db33095a1cf7a8887921a5ec969824
---
 sys/netinet/tcp_usrreq.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 3e73e448a9f7..c6713a0bb4cb 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -355,9 +355,10 @@ out:
 static int
 tcp_usr_listen(struct socket *so, int backlog, struct thread *td)
 {
-	int error = 0;
 	struct inpcb *inp;
 	struct tcpcb *tp;
+	int error = 0;
+	bool already_listening;
 
 	inp = sotoinpcb(so);
 	KASSERT(inp != NULL, ("tcp_usr_listen: inp == NULL"));
@@ -369,6 +370,7 @@ tcp_usr_listen(struct socket *so, int backlog, struct thread *td)
 	tp = intotcpcb(inp);
 
 	SOCK_LOCK(so);
+	already_listening = SOLISTENING(so);
 	error = solisten_proto_check(so);
 	if (error != 0) {
 		SOCK_UNLOCK(so);
@@ -390,6 +392,8 @@ tcp_usr_listen(struct socket *so, int backlog, struct thread *td)
 		solisten_proto_abort(so);
 	}
 	SOCK_UNLOCK(so);
+	if (already_listening)
+		goto out;
 
 	if (error == 0)
 		in_pcblisten(inp);
@@ -408,10 +412,11 @@ out:
 static int
 tcp6_usr_listen(struct socket *so, int backlog, struct thread *td)
 {
-	int error = 0;
 	struct inpcb *inp;
 	struct tcpcb *tp;
 	u_char vflagsav;
+	int error = 0;
+	bool already_listening;
 
 	inp = sotoinpcb(so);
 	KASSERT(inp != NULL, ("tcp6_usr_listen: inp == NULL"));
@@ -425,6 +430,7 @@ tcp6_usr_listen(struct socket *so, int backlog, struct thread *td)
 	vflagsav = inp->inp_vflag;
 
 	SOCK_LOCK(so);
+	already_listening = SOLISTENING(so);
 	error = solisten_proto_check(so);
 	if (error != 0) {
 		SOCK_UNLOCK(so);
@@ -449,6 +455,8 @@ tcp6_usr_listen(struct socket *so, int backlog, struct thread *td)
 		solisten_proto_abort(so);
 	}
 	SOCK_UNLOCK(so);
+	if (already_listening)
+		goto out;
 
 	if (error == 0)
 		in_pcblisten(inp);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202501280503.50S5385J010919>