conf: Treat --dns addresses as guest visible addresses
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 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 <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
a6066f4e27
commit
0b25cac94e
2 changed files with 53 additions and 51 deletions
90
conf.c
90
conf.c
|
@ -353,7 +353,7 @@ bind_all_fail:
|
|||
/**
|
||||
* add_dns4() - Possibly add the IPv4 address of a DNS resolver to configuration
|
||||
* @c: Execution context
|
||||
* @addr: Address found in /etc/resolv.conf
|
||||
* @addr: Guest nameserver IPv4 address
|
||||
* @idx: Index of free entry in array of IPv4 resolvers
|
||||
*
|
||||
* Return: Number of entries added (0 or 1)
|
||||
|
@ -361,64 +361,29 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_dns6() - Possibly add the IPv6 address of a DNS resolver to configuration
|
||||
* @c: Execution context
|
||||
* @addr: Address found in /etc/resolv.conf
|
||||
* @addr: Guest nameserver IPv6 address
|
||||
* @idx: Index of free entry in array of IPv6 resolvers
|
||||
*
|
||||
* 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))
|
||||
*idx4 += add_dns4(c, &ns4, *idx4);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
14
passt.1
14
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
|
||||
|
|
Loading…
Reference in a new issue