From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 4389D5A0320 for ; Wed, 14 Aug 2024 06:31:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202312; t=1723609853; bh=GR3B8fThEp5WdyRRImdaR9GRBbuYR5K2F7qym5Q1JTU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TsT27kUo9k5H5yaSrVD09HENrrCTu8hV5/aWVhbSNuDUCvvH0bfgkPBj1d43VC4hQ 8mYDf/3NLe65KxhSSsBObXWAhnppYrVo5G7stM2eYAplVQ24rtQ0bh6qlC/hnHgfrl TkBN5b2z3OdTfbeq6vsEQgYfcoTDwufvitUDGxlMhRofriLFVQbjob1JF6QH9+XzxB EeDSoQS8gEDaxesOybQm9T19zpNwAQt163WjTopS7bCHcmuTE0TYC7P6yBBanOqL6Y LtsAkLR88vKlfsTyedDTbmLSFYp2p9dppFB9ao8EEiw9bykD5ewRivz7DRUjcO0+lX vD+g+0e60kOhg== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4WkFgK2HQ9z4xDF; Wed, 14 Aug 2024 14:30:53 +1000 (AEST) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH 11/16] conf: Treat --dns addresses as guest visible addresses Date: Wed, 14 Aug 2024 14:30:45 +1000 Message-ID: <20240814043050.4177037-12-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240814043050.4177037-1-david@gibson.dropbear.id.au> References: <20240814043050.4177037-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: XTWGTN63WVFH5YOOK2CCHOA4TZVNTV5X X-Message-ID-Hash: XTWGTN63WVFH5YOOK2CCHOA4TZVNTV5X 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: Although it's not 100% explicit in the man page, addresses given to the --dns option are intended to be addresses as seen by the guest. This differs from addresses taken from the host's /etc/resolv.conf, which must be translated to to guest accessible versions in some cases. Our implementation is currently inconsistent on this: when using --dns-forward, you must usually also give --dns with the matching address, which is meaningful only in the guest's address view. However if you give --dns with a loopback addres, it will be translated like a host view address. Move the remapping logic for DNS addresses out of add_dns4() and add_dns6() into add_dns_resolv() so that it is only applied for host nameserver addresses, not for nameservers given explicitly with --dns. Signed-off-by: David Gibson --- conf.c | 84 ++++++++++++++++++++++++++++----------------------------- passt.1 | 14 ++++++---- 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/conf.c b/conf.c index cb462b09..fa6d90ef 100644 --- a/conf.c +++ b/conf.c @@ -361,29 +361,11 @@ bind_all_fail: static unsigned add_dns4(struct ctx *c, const struct in_addr *addr, unsigned idx) { - unsigned added = 0; - if (idx >= ARRAY_SIZE(c->ip4.dns)) return 0; - /* Guest or container can only access local addresses via redirect */ - if (IN4_IS_ADDR_LOOPBACK(addr)) { - if (!c->no_map_gw) { - c->ip4.dns[idx] = c->ip4.gw; - added++; - - if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_match)) - c->ip4.dns_match = c->ip4.gw; - } - } else { - c->ip4.dns[idx] = *addr; - added++; - } - - if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_host)) - c->ip4.dns_host = *addr; - - return added; + c->ip4.dns[idx] = *addr; + return 1; } /** @@ -394,31 +376,14 @@ static unsigned add_dns4(struct ctx *c, const struct in_addr *addr, * * Return: Number of entries added (0 or 1) */ -static unsigned add_dns6(struct ctx *c, struct in6_addr *addr, unsigned idx) +static unsigned add_dns6(struct ctx *c, const struct in6_addr *addr, + unsigned idx) { - unsigned added = 0; - if (idx >= ARRAY_SIZE(c->ip6.dns)) return 0; - /* Guest or container can only access local addresses via redirect */ - if (IN6_IS_ADDR_LOOPBACK(addr)) { - if (!c->no_map_gw) { - c->ip6.dns[idx] = c->ip6.gw; - added++; - - if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match)) - c->ip6.dns_match = c->ip6.gw; - } - } else { - c->ip6.dns[idx] = *addr; - added++; - } - - if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_host)) - c->ip6.dns_host = *addr; - - return added; + c->ip6.dns[idx] = *addr; + return 1; } /** @@ -437,11 +402,44 @@ static void add_dns_resolv(struct ctx *c, const char *nameserver, struct in6_addr ns6; struct in_addr ns4; - if (idx4 && inet_pton(AF_INET, nameserver, &ns4)) + if (idx4 && inet_pton(AF_INET, nameserver, &ns4)) { + if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_host)) + c->ip4.dns_host = ns4; + + /* Guest or container can only access local addresses via + * redirect + */ + if (IN4_IS_ADDR_LOOPBACK(&ns4)) { + if (c->no_map_gw) + return; + + ns4 = c->ip4.gw; + if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_match)) + c->ip4.dns_match = c->ip4.gw; + } + *idx4 += add_dns4(c, &ns4, *idx4); + } + + if (idx6 && inet_pton(AF_INET6, nameserver, &ns6)) { + if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_host)) + c->ip6.dns_host = ns6; + + /* Guest or container can only access local addresses via + * redirect + */ + if (IN6_IS_ADDR_LOOPBACK(&ns6)) { + if (c->no_map_gw) + return; + + ns6 = c->ip6.gw; + + if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match)) + c->ip6.dns_match = c->ip6.gw; + } - if (idx6 && inet_pton(AF_INET6, nameserver, &ns6)) *idx6 += add_dns6(c, &ns6, *idx6); + } } /** diff --git a/passt.1 b/passt.1 index 3062b719..dca433b6 100644 --- a/passt.1 +++ b/passt.1 @@ -236,11 +236,15 @@ interface will be chosen instead. .TP .BR \-D ", " \-\-dns " " \fIaddr -Use \fIaddr\fR (IPv4 or IPv6) for DHCP, DHCPv6, NDP or DNS forwarding, as -configured (see options \fB--no-dhcp-dns\fR, \fB--dhcp-dns\fR, -\fB--dns-forward\fR) instead of reading addresses from \fI/etc/resolv.conf\fR. -This option can be specified multiple times. Specifying \fB-D none\fR disables -usage of DNS addresses altogether. +Instruct the guest (via DHCP, DHVPv6 or NDP) to use \fIaddr\fR (IPv4 +or IPv6) as a nameserver, as configured (see options +\fB--no-dhcp-dns\fR, \fB--dhcp-dns\fR) instead of reading addresses +from \fI/etc/resolv.conf\fR. This option can be specified multiple +times. Specifying \fB-D none\fR disables usage of DNS addresses +altogether. Unlike addresses from \fI/etc/resolv.conf\fR, \fIaddr\fR +is given to the guest without remapping. For example \fB--dns +127.0.0.1\fR will instruct the guest to use itself as nameserver, not +the host. .TP .BR \-\-dns-forward " " \fIaddr -- 2.46.0