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=V6NcmxKU; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 8D06C5A0BCC for ; Tue, 02 Dec 2025 05:02:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202510; t=1764648138; bh=loz1Ho9ASUwEAjy4feMGxVQEQ6FrWEmyNW2kPFBL7gs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=V6NcmxKUI5A/M+ujCMtvw3vYUTNBlgO4ZJQaYPN9Piyy6p4b1GcqB1TPIqt9aFa5v JgcFJAbi6KkJsKpTlAW/RRqYXT/HWwBNV73U3qHozJKxs8cCHXDz3ZO0nLO3Y4RxZf lWBNwXbEKOzrHIwhD6VE1KmYb+I7TPX84+GllDEFIy5NqJo89o+RoaysrX8C5i6W7g LY6oJFExRKCpNWzr1NE0bUrsWo2wwSo0IvcJSaF3dVeLw/aM6OdygT5wyHr7oXKX/J +eFttFcUZ+YtSDYTAOq2VqFqNAyooDWqnupgC411DNIi0SUWr+2QcrPhWragePEx+q SzzsjWRFS+VCg== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4dL6Y61pBhz4wQk; Tue, 02 Dec 2025 15:02:18 +1100 (AEDT) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH v5 14/15] tcp: Always populate oaddr field for socket initiated flows Date: Tue, 2 Dec 2025 15:02:14 +1100 Message-ID: <20251202040215.2351792-15-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251202040215.2351792-1-david@gibson.dropbear.id.au> References: <20251202040215.2351792-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: KZEP7M7LFXUN3VERU5A66WQDZYTDBZHG X-Message-ID-Hash: KZEP7M7LFXUN3VERU5A66WQDZYTDBZHG 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 aacc5b20..535d6cfa 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.52.0