From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gandalf.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 839585A0275 for ; Mon, 1 May 2023 13:08:10 +0200 (CEST) Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4Q90n05rG5z4x4C; Mon, 1 May 2023 21:08:04 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=201602; t=1682939284; bh=Zi7hmg0SJsOTDqgYmoecqFTIyeQ9Ac7PPjitYAgJUzM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qO2gHZZo+k/nhsqhgqHmsLmh4y0kffTt7UyehoRavZ7lJGQDBBJv3T5sQlM6wlX+I z9UmZ+VkyfbIDBIGW4/Tp/Hf+ZFurm1YNvJRS+LjQGv9jussKWRK1x2iBaiutEiAHm EvZffe9AJj5FxuJ2qt9cn+gucXaL+k2v6e8VBHhM= From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH 6/7] Allow nat-to-host addresses to be overridden Date: Mon, 1 May 2023 21:07:01 +1000 Message-Id: <20230501110702.3915529-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230501110702.3915529-1-david@gibson.dropbear.id.au> References: <20230501110702.3915529-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: PFFJOCIMRUVDPVPYNVPB76UADTCB7T6Z X-Message-ID-Hash: PFFJOCIMRUVDPVPYNVPB76UADTCB7T6Z 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: Because the host and guest share the same IP address with passt/pasta, it's not possible for the guest to directly address the host. Therefore we allow packets from the guest going to a special "NAT to host" address to be redirected to the host, appearing there as though they have both source and destination address of loopback. Currently that special address is always the address of the default gateway. That can be a problem if we want that gateway to be addressable by the guest. Therefore, allow the special "NAT to host" address to be overridden on the command line. Signed-off-by: David Gibson --- conf.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/conf.c b/conf.c index 45f49eb..ea56003 100644 --- a/conf.c +++ b/conf.c @@ -849,6 +849,12 @@ static void usage(const char *name) else info(" --no-dhcp-search No list in DHCP/DHCPv6/NDP"); + info( " -H, --nat-to-host ADDR NAT packets sent to ADDR to go to host"); + info( " NATted packets will appear on the host to have come from"); + info( " foopback. Can be specified zero to two times (for IPv4 and IPv6)"); + info( " default: gateway address, or no NAT if --no-map-gw is also"); + info( " specified"); + info( " --dns-forward ADDR Forward DNS queries sent to ADDR"); info( " can be specified zero to two times (for IPv4 and IPv6)"); info( " default: don't forward DNS queries"); @@ -987,6 +993,11 @@ static void conf_print(const struct ctx *c) c->mac[3], c->mac[4], c->mac[5]); if (c->ifi4) { + if (!IN4_IS_ADDR_UNSPECIFIED(&c->ip4.nattohost)) + info(" NAT for host 127.0.0.1: %s", + inet_ntop(AF_INET, &c->ip4.nattohost, + buf4, sizeof(buf4))); + if (!c->no_dhcp) { uint32_t mask; @@ -1016,6 +1027,11 @@ static void conf_print(const struct ctx *c) } if (c->ifi6) { + if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.nattohost)) + info(" NAT for host ::1: %s", + inet_ntop(AF_INET6, &c->ip6.nattohost, + buf6, sizeof(buf6))); + if (!c->no_ndp && !c->no_dhcpv6) info("NDP/DHCPv6:"); else if (!c->no_ndp) @@ -1191,6 +1207,7 @@ void conf(struct ctx *c, int argc, char **argv) {"netmask", required_argument, NULL, 'n' }, {"mac-addr", required_argument, NULL, 'M' }, {"gateway", required_argument, NULL, 'g' }, + {"host", required_argument, NULL, 'H' }, {"interface", required_argument, NULL, 'i' }, {"outbound", required_argument, NULL, 'o' }, {"dns", required_argument, NULL, 'D' }, @@ -1245,9 +1262,9 @@ void conf(struct ctx *c, int argc, char **argv) if (c->mode == MODE_PASTA) { c->no_dhcp_dns = c->no_dhcp_dns_search = 1; - optstring = "dqfel:hF:I:p:P:m:a:n:M:g:i:o:D:S:46t:u:T:U:"; + optstring = "dqfel:hF:I:p:P:m:a:n:M:g:i:o:D:S:46t:u:T:U:H:"; } else { - optstring = "dqfel:hs:F:p:P:m:a:n:M:g:i:o:D:S:461t:u:"; + optstring = "dqfel:hs:F:p:P:m:a:n:M:g:i:o:D:S:461t:u:H:"; } c->tcp.fwd_in.mode = c->tcp.fwd_out.mode = 0; @@ -1548,6 +1565,23 @@ void conf(struct ctx *c, int argc, char **argv) die("Invalid gateway address: %s", optarg); break; + case 'H': + if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.nattohost) && + inet_pton(AF_INET6, optarg, &c->ip6.nattohost)&& + !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.nattohost) && + !IN6_IS_ADDR_LOOPBACK(&c->ip6.nattohost)) + break; + + if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.nattohost) && + inet_pton(AF_INET, optarg, &c->ip4.nattohost) && + !IN4_IS_ADDR_UNSPECIFIED(&c->ip4.nattohost) && + !IN4_IS_ADDR_BROADCAST(&c->ip4.nattohost) && + !IN4_IS_ADDR_LOOPBACK(&c->ip4.nattohost)) + break; + + err("Invalid host remap address: %s", optarg); + usage(argv[0]); + break; case 'i': if (ifi4 || ifi6) die("Redundant interface: %s", optarg); -- 2.40.1