From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id DAE615A0051 for ; Fri, 14 Jun 2024 08:14:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202312; t=1718345632; bh=+IBXLzSufYQM8TtqaFrslQDEuaULS8UGzGN0vXMpJhA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f0MDpZubAi2X7qQfkzYV4CdVdOU794sw+SoYWTFBhuBTsCKrLg9TTyxntKbBKfSMp zqgDArB9TRKjmJwz0xdx6obZGV2PfMSku3CfyOY7ZVkLb9NgRjvhLfEMzQeS1TGfhk woHO5GVc5d3O7Q65q8rfWsPb1A9RMCalOY0++RH5V/pLO7dYaM/MjpvTv0BzqqBgd/ HwecDg1QMZN5szzUhiHyw/kTxrb1rUR2mK2evRsZgRqdc7ktz+7Jzm/C10cro+pkJq PJfOf6xHggiNBUM6+jpn9MdtTkEzx3+eR4ZiCg7bqcxPb7Whw2ZKXF7nGluDWmaP1H OfTzGQTWL07Mw== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4W0prJ2x1Nz4x1C; Fri, 14 Jun 2024 16:13:52 +1000 (AEST) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH v6 18/26] fwd: Update flow forwarding logic for UDP Date: Fri, 14 Jun 2024 16:13:40 +1000 Message-ID: <20240614061348.3814736-19-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240614061348.3814736-1-david@gibson.dropbear.id.au> References: <20240614061348.3814736-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: 6JAAMOWFLA355KIQGK2JR6L3EKUMY6RN X-Message-ID-Hash: 6JAAMOWFLA355KIQGK2JR6L3EKUMY6RN 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: jmaloy@redhat.com, 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: Add logic to the fwd_nat_from_*() functions to forwarding UDP packets. The logic here doesn't exactly match our current forwarding, since our current forwarding has some very strange and buggy edge cases. Instead it's attempting to replicate what appears to be the intended logic behind the current forwarding. Signed-off-by: David Gibson --- fwd.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/fwd.c b/fwd.c index 7ad7f07b..cd66eaee 100644 --- a/fwd.c +++ b/fwd.c @@ -169,12 +169,15 @@ void fwd_scan_ports_init(struct ctx *c) uint8_t fwd_nat_from_tap(const struct ctx *c, uint8_t proto, const struct flowside *ini, struct flowside *tgt) { - (void)proto; - tgt->eaddr = ini->faddr; tgt->eport = ini->fport; - if (!c->no_map_gw) { + if (proto == IPPROTO_UDP && tgt->eport == 53) { + if (inany_equals4(&tgt->eaddr, &c->ip4.dns_match)) + tgt->eaddr = inany_from_v4(c->ip4.dns_host); + else if (inany_equals6(&tgt->eaddr, &c->ip6.dns_match)) + tgt->eaddr.a6 = c->ip6.dns_host; + } else if (!c->no_map_gw) { if (inany_equals4(&tgt->eaddr, &c->ip4.gw)) tgt->eaddr = inany_loopback4; else if (inany_equals6(&tgt->eaddr, &c->ip6.gw)) @@ -191,6 +194,10 @@ uint8_t fwd_nat_from_tap(const struct ctx *c, uint8_t proto, /* Let the kernel pick a host side source port */ tgt->fport = 0; + if (proto == IPPROTO_UDP) { + /* But for UDP we preserve the source port */ + tgt->fport = ini->eport; + } return PIF_HOST; } @@ -227,9 +234,14 @@ uint8_t fwd_nat_from_splice(const struct ctx *c, uint8_t proto, tgt->eport = ini->fport; if (proto == IPPROTO_TCP) tgt->eport += c->tcp.fwd_out.delta[tgt->eport]; + else if (proto == IPPROTO_UDP) + tgt->eport += c->udp.fwd_out.f.delta[tgt->eport]; /* Let the kernel pick a host side source port */ tgt->fport = 0; + if (proto == IPPROTO_UDP) + /* But for UDP preserve the source port */ + tgt->fport = ini->eport; return PIF_HOST; } @@ -251,18 +263,24 @@ uint8_t fwd_nat_from_host(const struct ctx *c, uint8_t proto, tgt->eport = ini->fport; if (proto == IPPROTO_TCP) tgt->eport += c->tcp.fwd_in.delta[tgt->eport]; + else if (proto == IPPROTO_UDP) + tgt->eport += c->udp.fwd_in.f.delta[tgt->eport]; if (c->mode == MODE_PASTA && inany_is_loopback(&ini->eaddr) && - proto == IPPROTO_TCP) { + (proto == IPPROTO_TCP || proto == IPPROTO_UDP)) { /* spliceable */ tgt->faddr = ini->eaddr; /* Let the kernel pick a namespace side source port */ tgt->fport = 0; + if (proto == IPPROTO_UDP) + /* But for UDP preserve the source port */ + tgt->fport = ini->eport; if (inany_v4(&ini->eaddr)) tgt->eaddr = inany_loopback4; else tgt->eaddr = inany_loopback6; + return PIF_SPLICE; } -- 2.45.2