On Fri, Apr 11, 2025 at 11:14:39AM +0200, Stefano Brivio wrote: > If the first resolver listed in the host's /etc/resolv.conf is a > loopback address, and --no-map-gw is given, we automatically conclude > that the resolver is not reachable, discard it, and, if it's the only > nameserver listed in /etc/resolv.conf, we'll warn that we: > > Couldn't get any nameserver address > > However, this isn't true in a general case: the user might have passed > --dns-forward, and in that case, while we won't map the address of the > default gateway to the host, we're still supposed to map that > particular address. Otherwise, in this common Podman usage: > > pasta --config-net --dns-forward 169.254.1.1 -t none -u none -T none -U none --no-map-gw --netns /run/user/1000/netns/netns-c02a8d8f-6ee3-902e-33c5-317e0f24e0af --map-guest-addr 169.254.1.2 > > and with a loopback address in /etc/resolv.conf, we'll unexpectedly > refuse to forward DNS queries: > > # nslookup passt.top 169.254.1.1 > ;; connection timed out; no servers could be reached > > To fix this, make an exception for --dns-forward: if &c->ip4.dns_match > or &c->ip6.dns_match are set in add_dns_resolv4() / add_dns_resolv6(), > use that address as guest-facing resolver. > > We already set 'dns_host' to the address we found in /etc/resolv.conf, > that's correct in this case and it makes us forward queries as > expected. > > I'm not changing the man page as the current description of > --dns-forward is already consistent with the new behaviour: there's no > described way in which --no-map-gw should affect it. > > Reported-by: Andrew Sayers > Link: https://bugs.passt.top/show_bug.cgi?id=111 > Suggested-by: Paul Holzinger > Signed-off-by: Stefano Brivio Reviewed-by: David Gibson > --- > conf.c | 30 ++++++++++++++++++++++-------- > 1 file changed, 22 insertions(+), 8 deletions(-) > > diff --git a/conf.c b/conf.c > index 18ed11c..f942851 100644 > --- a/conf.c > +++ b/conf.c > @@ -431,12 +431,19 @@ static void add_dns_resolv4(struct ctx *c, struct in_addr *ns, unsigned *idx) > */ > if (IN4_IS_ADDR_LOOPBACK(ns) || > IN4_ARE_ADDR_EQUAL(ns, &c->ip4.map_host_loopback)) { > - if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.map_host_loopback)) > - return; > + if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_match)) { > + if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.map_host_loopback)) > + return; /* Address unreachable */ > > - *ns = c->ip4.map_host_loopback; > - if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_match)) > + *ns = c->ip4.map_host_loopback; > c->ip4.dns_match = c->ip4.map_host_loopback; > + } else { > + /* No general host mapping, but requested for DNS > + * (--dns-forward and --no-map-gw): advertise resolver > + * address from --dns-forward, and map that to loopback > + */ > + *ns = c->ip4.dns_match; > + } > } > > *idx += add_dns4(c, ns, *idx); > @@ -459,12 +466,19 @@ static void add_dns_resolv6(struct ctx *c, struct in6_addr *ns, unsigned *idx) > */ > if (IN6_IS_ADDR_LOOPBACK(ns) || > IN6_ARE_ADDR_EQUAL(ns, &c->ip6.map_host_loopback)) { > - if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.map_host_loopback)) > - return; > + if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match)) { > + if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.map_host_loopback)) > + return; /* Address unreachable */ > > - *ns = c->ip6.map_host_loopback; > - if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match)) > + *ns = c->ip6.map_host_loopback; > c->ip6.dns_match = c->ip6.map_host_loopback; > + } else { > + /* No general host mapping, but requested for DNS > + * (--dns-forward and --no-map-gw): advertise resolver > + * address from --dns-forward, and map that to loopback > + */ > + *ns = c->ip6.dns_match; > + } > } > > *idx += add_dns6(c, ns, *idx); -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson