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=qrGppihj; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id A5EEE5A0625 for ; Sat, 11 Oct 2025 06:49:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202510; t=1760158165; bh=A3ECtzEslyWfcDN7t7XLiL68nMuAxzXrSBP2bwTe2JI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qrGppihj3mVigBZyWC4Ioq3LEIwqoiKPzw9S/mE7Cks1e/ylnRmzTZ3FH5sa/tDUz uIpTa9OqZGmkjy/1NwtI5MAKO2JMqnbtgeCTn5NtUSSsmBQ4Dw7bk6Znm9lMpN1Q0X SYIR0egxgK4KVfXMtpeRodnfQ/guEnEM79Ml/iRG+n3JiTnLBk4qySPhKkSAwe2jkl Jsn+IMKM1noVmkfKbuuoyW2h2N+YUt1YUmL0+ID/3lykQjrOOZm5EaxbFQ9jSgRVeh noa6wzKLuX3J71pSlBuhhTjK3XW1R6wb+h57veA2PVdlogAVYcCaYIor5UtHDkSLpQ mjIuSxYkmFZeA== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4ckB3T5g2Xz4wD9; Sat, 11 Oct 2025 15:49:25 +1100 (AEDT) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH 7/8] fwd: Update all port maps before applying exclusions Date: Sat, 11 Oct 2025 15:48:26 +1100 Message-ID: <20251011044827.862757-8-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251011044827.862757-1-david@gibson.dropbear.id.au> References: <20251011044827.862757-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: BA3TYUWFGSKF3NQNP6YBOZOMDWOMCXZD X-Message-ID-Hash: BA3TYUWFGSKF3NQNP6YBOZOMDWOMCXZD 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: In fwd_scan_ports() we go through each of the automatic forwarding cases (tcp, udp, inbound and outbound) in turn, scanning and calculating the new forwarding map. However, to avoid avoid circular forwarding, some of these maps affect each other. This has the odd effect that the ones handled earlier are based on the previous scan of other maps, whereas the later ones are based on the latest scan. That's not generally harmful, but it is counter-intuitive and results in a few odd edge cases. Avoid this by performing all the scans first, without regard to other maps, then applying the exclusions afterwards. One case has an extra wrinkle: for UDP we forwarded not just ports that were listening on UDP but ones listening on TCP as well, for the benefit of protocols like iperf3. We therefore also excluded listening ports from both UDP and TCP from the other direction to avoid circular forwarding. This doesn't really make sense, though. To avoid circular forwarding, we don't care *why* the other side is listening on UDP, just that it *is* listening. I believe the explicit handling of the reverse TCP map was only needed because the reverse map might have been one cycle out of date and therefore not included a port opened because of the corresponding TCP port. Now that we avoid that out of date map possibility, it's sufficient to just mask out UDP listening ports in the other direction. Signed-off-by: David Gibson --- fwd.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/fwd.c b/fwd.c index 57941759..395b0def 100644 --- a/fwd.c +++ b/fwd.c @@ -146,10 +146,8 @@ static void procfs_scan_listen(int fd, unsigned int lstate, uint8_t *map) /** * fwd_scan_ports_tcp() - Scan /proc to update TCP forwarding map * @fwd: Forwarding information to update - * @rev: Forwarding information for the reverse direction */ -static void fwd_scan_ports_tcp(struct fwd_ports *fwd, - const struct fwd_ports *rev) +static void fwd_scan_ports_tcp(struct fwd_ports *fwd) { if (fwd->mode != FWD_AUTO) return; @@ -157,20 +155,15 @@ static void fwd_scan_ports_tcp(struct fwd_ports *fwd, memset(fwd->map, 0, PORT_BITMAP_SIZE); procfs_scan_listen(fwd->scan4, TCP_LISTEN, fwd->map); procfs_scan_listen(fwd->scan6, TCP_LISTEN, fwd->map); - bitmap_andc(fwd->map, PORT_BITMAP_SIZE, fwd->map, rev->map); } /** * fwd_scan_ports_udp() - Scan /proc to update UDP forwarding map * @fwd: Forwarding information to update - * @rev: Forwarding information for the reverse direction * @tcp_fwd: Corresponding TCP forwarding information - * @tcp_rev: TCP forwarding information for the reverse direction */ static void fwd_scan_ports_udp(struct fwd_ports *fwd, - const struct fwd_ports *rev, - const struct fwd_ports *tcp_fwd, - const struct fwd_ports *tcp_rev) + const struct fwd_ports *tcp_fwd) { if (fwd->mode != FWD_AUTO) return; @@ -186,15 +179,6 @@ static void fwd_scan_ports_udp(struct fwd_ports *fwd, */ procfs_scan_listen(tcp_fwd->scan4, TCP_LISTEN, fwd->map); procfs_scan_listen(tcp_fwd->scan6, TCP_LISTEN, fwd->map); - - /* - * This means we need to skip numbers of TCP ports bound on the other - * side, too. Otherwise, we would detect corresponding UDP ports as - * bound and try to forward them from the opposite side, but it's - * already us handling them. - */ - bitmap_andc(fwd->map, PORT_BITMAP_SIZE, fwd->map, rev->map); - bitmap_andc(fwd->map, PORT_BITMAP_SIZE, fwd->map, tcp_rev->map); } /** @@ -203,12 +187,28 @@ static void fwd_scan_ports_udp(struct fwd_ports *fwd, */ static void fwd_scan_ports(struct ctx *c) { - fwd_scan_ports_tcp(&c->tcp.fwd_out, &c->tcp.fwd_in); - fwd_scan_ports_tcp(&c->tcp.fwd_in, &c->tcp.fwd_out); - fwd_scan_ports_udp(&c->udp.fwd_out, &c->udp.fwd_in, - &c->tcp.fwd_out, &c->tcp.fwd_in); - fwd_scan_ports_udp(&c->udp.fwd_in, &c->udp.fwd_out, - &c->tcp.fwd_in, &c->tcp.fwd_out); + fwd_scan_ports_tcp(&c->tcp.fwd_out); + fwd_scan_ports_tcp(&c->tcp.fwd_in); + fwd_scan_ports_udp(&c->udp.fwd_out, &c->tcp.fwd_out); + fwd_scan_ports_udp(&c->udp.fwd_in, &c->tcp.fwd_in); + + if (c->tcp.fwd_out.mode == FWD_AUTO) { + bitmap_andc(c->tcp.fwd_out.map, PORT_BITMAP_SIZE, + c->tcp.fwd_out.map, c->tcp.fwd_in.map); + } + if (c->tcp.fwd_in.mode == FWD_AUTO) { + bitmap_andc(c->tcp.fwd_in.map, PORT_BITMAP_SIZE, + c->tcp.fwd_in.map, c->tcp.fwd_out.map); + } + + if (c->udp.fwd_out.mode == FWD_AUTO) { + bitmap_andc(c->udp.fwd_out.map, PORT_BITMAP_SIZE, + c->udp.fwd_out.map, c->udp.fwd_in.map); + } + if (c->udp.fwd_in.mode == FWD_AUTO) { + bitmap_andc(c->udp.fwd_in.map, PORT_BITMAP_SIZE, + c->udp.fwd_in.map, c->udp.fwd_out.map); + } } /** -- 2.51.0