From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202510 header.b=Ex10EmpP; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 5FC475A0271 for ; Thu, 20 Nov 2025 05:34:59 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202510; t=1763613296; bh=4EM2k5+IIUN61sPffxyBl7LYnu/iunb8DU5hCFwX/R0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ex10EmpP3qpjmxKGSqTY1WEfccqz/ArCod1uhgWCemZINdaO3J+UIaCvS254DMwBe ULY4SJYG7hGfl4VUm8GgJSeSHKaCowQIVPjzxHgYrz4iy7CCW9uHxQj3sLpFU46mnx clh3q74vQknHKsUKJvvYBEURu5WfVB85V5oZmqwhw+AvpRHpnAm1a8Ffh3PBBmV9KH geUcfHWkYIGPH5XkFq+uSXdc+Ur9cucVlR8YCLtlBZPbGPfJc+euSR7xS1W0PNd94y SwYgsFYWXulrjONhPYH0X2cojyKjbOZFCoAps79UFtf284Y3bFyXcGYJZJgSryfna5 t1qIGFPYPKZ3g== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4dBlrJ2BLYz4wHL; Thu, 20 Nov 2025 15:34:56 +1100 (AEDT) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH 2/3] tcp: Always populate oaddr field for socket initiated flows Date: Thu, 20 Nov 2025 15:34:52 +1100 Message-ID: <20251120043453.108919-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251120043453.108919-1-david@gibson.dropbear.id.au> References: <20251120043453.108919-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: DSM3XYSPW2R4ZEMRM5RMXLZ4XVZCW5KZ X-Message-ID-Hash: DSM3XYSPW2R4ZEMRM5RMXLZ4XVZCW5KZ X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: David Gibson X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: When we receive a TCP connection, we get the peer address from the accept() call. In the case of a listening socket with an unspecified address (:: or 0.0.0.0) the local address of the accept()ed socket could vary. We don't get that from the accept() - we must explicitly call getsockname() to get it. Currently we avoid the latency of that extra syscall, and therefore don't populate the initiating 'oaddr' field of a flow created by an incoming TCP socket connection. This more or less works, because we rarely need that local address, but it does cause some oddities: * For migration we need the local address to recreate the socket on the destination, so we *do* call getsockname() in vhost-user mode * It limits our options in terms of forwarding connections flexibly based on the address to which they're received * It differs from UDP, where we explicitly use the IP_PKTINFO cmsg to populate oaddr. * It means (some) flow debug messages will contain wildcards instead of real local addresses In theory we can elide this call when accept()ing from a socket bound to a specific address instead of a wildcard. However to do that will need revisions to the data structures we use to keep track of listening sockets. The lack of this information is making it hard to implement some fixes we want. So, pay the price of the extra syscall to get this information, with the hope that we can later optimise it away for some cases. Signed-off-by: David Gibson --- tcp.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tcp.c b/tcp.c index bd25952f..e734a957 100644 --- a/tcp.c +++ b/tcp.c @@ -2354,11 +2354,9 @@ void tcp_listen_handler(const struct ctx *c, union epoll_ref ref, ini = flow_initiate_sa(flow, ref.tcp_listen.pif, &sa, NULL, ref.tcp_listen.port); - if (c->mode == MODE_VU) { /* Rebind to same address after migration */ - if (getsockname(s, &sa.sa, &sl) || - inany_from_sockaddr(&ini->oaddr, &ini->oport, &sa) < 0) - err_perror("Can't get local address for socket %i", s); - } + if (getsockname(s, &sa.sa, &sl) || + inany_from_sockaddr(&ini->oaddr, &ini->oport, &sa) < 0) + err_perror("Can't get local address for socket %i", s); if (!inany_is_unicast(&ini->eaddr) || ini->eport == 0) { char sastr[SOCKADDR_STRLEN]; -- 2.51.1