diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2022-02-18 04:03:53 +0100 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2022-02-21 13:41:13 +0100 |
commit | 89678c515755403277938e34984f3faf4863d593 (patch) | |
tree | 2e704fe4f036cc017e27be5103098b70e4954c75 /conf.c | |
parent | 01ae772dcc4ba7930179521bb22712bb4256bb03 (diff) | |
download | passt-89678c515755403277938e34984f3faf4863d593.tar passt-89678c515755403277938e34984f3faf4863d593.tar.gz passt-89678c515755403277938e34984f3faf4863d593.tar.bz2 passt-89678c515755403277938e34984f3faf4863d593.tar.lz passt-89678c515755403277938e34984f3faf4863d593.tar.xz passt-89678c515755403277938e34984f3faf4863d593.tar.zst passt-89678c515755403277938e34984f3faf4863d593.zip |
conf, udp: Introduce basic DNS forwarding
For compatibility with libslirp/slirp4netns users: introduce a
mechanism to map, in the UDP routines, an address facing guest or
namespace to the first IPv4 or IPv6 address resulting from
configuration as resolver. This can be enabled with the new
--dns-forward option.
This implies that sourcing and using DNS addresses and search lists,
passed via command line or read from /etc/resolv.conf, is not bound
anymore to DHCP/DHCPv6/NDP usage: for example, pasta users might just
want to use addresses from /etc/resolv.conf as mapping target, while
not passing DNS options via DHCP.
Reflect this in all the involved code paths by differentiating
DHCP/DHCPv6/NDP usage from DNS configuration per se, and in the new
options --dhcp-dns, --dhcp-search for pasta, and --no-dhcp-dns,
--no-dhcp-search for passt.
This should be the last bit to enable substantial compatibility
between slirp4netns.sh and slirp4netns(1): pass the --dns-forward
option from the script too.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'conf.c')
-rw-r--r-- | conf.c | 102 |
1 files changed, 81 insertions, 21 deletions
@@ -279,7 +279,7 @@ static void get_dns(struct ctx *c) dns4_set = !c->v4 || !!*dns4; dns6_set = !c->v6 || !IN6_IS_ADDR_UNSPECIFIED(dns6); dnss_set = !!*s->n || c->no_dns_search; - dns_set = dns4_set || dns6_set || c->no_dns; + dns_set = (dns4_set && dns6_set) || c->no_dns; if (dns_set && dnss_set) return; @@ -583,21 +583,35 @@ static void usage(const char *name) info( " default: gateway from interface with default route"); info( " -i, --interface NAME Interface for addresses and routes"); info( " default: interface with first default route"); - info( " -D, --dns ADDR Pass IPv4 or IPv6 address as DNS"); + info( " -D, --dns ADDR Use IPv4 or IPv6 address as DNS"); info( " can be specified multiple times"); info( " a single, empty option disables DNS information"); if (strstr(name, "pasta")) - info( " default: don't send any addresses"); + info( " default: don't use any addresses"); else info( " default: use addresses from /etc/resolv.conf"); info( " -S, --search LIST Space-separated list, search domains"); info( " a single, empty option disables the DNS search list"); if (strstr(name, "pasta")) - info( " default: don't send any search list"); + info( " default: don't use any search list"); else info( " default: use search list from /etc/resolv.conf"); + if (strstr(name, "pasta")) + info(" --dhcp-dns: \tPass DNS list via DHCP/DHCPv6/NDP"); + else + info(" --no-dhcp-dns: No DNS list in DHCP/DHCPv6/NDP"); + + if (strstr(name, "pasta")) + info(" --dhcp-search: Pass list via DHCP/DHCPv6/NDP"); + else + info(" --no-dhcp-search: No list in DHCP/DHCPv6/NDP"); + + 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"); + info( " --no-tcp Disable TCP protocol handler"); info( " --no-udp Disable UDP protocol handler"); info( " --no-icmp Disable ICMP/ICMPv6 protocol handler"); @@ -699,22 +713,18 @@ void conf_print(struct ctx *c) info(" router: %s", inet_ntop(AF_INET, &c->gw4, buf4, sizeof(buf4))); } - } - if (!c->no_dns && !(c->no_dhcp && c->no_ndp && c->no_dhcpv6)) { for (i = 0; c->dns4[i]; i++) { if (!i) - info(" DNS:"); + info("DNS:"); inet_ntop(AF_INET, &c->dns4[i], buf4, sizeof(buf4)); - info(" %s", buf4); + info(" %s", buf4); } - } - if (!c->no_dns_search && !(c->no_dhcp && c->no_ndp && c->no_dhcpv6)) { for (i = 0; *c->dns_search[i].n; i++) { if (!i) - info(" search:"); - info(" %s", c->dns_search[i].n); + info("DNS search list:"); + info(" %s", c->dns_search[i].n); } } @@ -728,7 +738,7 @@ void conf_print(struct ctx *c) else if (!c->no_dhcpv6) info("NDP:"); else - return; + goto dns6; info(" assign: %s", inet_ntop(AF_INET6, &c->addr6, buf6, sizeof(buf6))); @@ -737,17 +747,18 @@ void conf_print(struct ctx *c) info(" our link-local: %s", inet_ntop(AF_INET6, &c->addr6_ll, buf6, sizeof(buf6))); +dns6: for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[i]); i++) { if (!i) - info(" DNS:"); + info("DNS:"); inet_ntop(AF_INET6, &c->dns6[i], buf6, sizeof(buf6)); - info(" %s", buf6); + info(" %s", buf6); } for (i = 0; *c->dns_search[i].n; i++) { if (!i) - info(" search:"); - info(" %s", c->dns_search[i].n); + info("DNS search list:"); + info(" %s", c->dns_search[i].n); } } } @@ -797,6 +808,11 @@ void conf(struct ctx *c, int argc, char **argv) {"nsrun-dir", required_argument, NULL, 3 }, {"config-net", no_argument, &c->pasta_conf_ns, 1 }, {"ns-mac-addr", required_argument, NULL, 4 }, + {"dhcp-dns", no_argument, NULL, 5 }, + {"no-dhcp-dns", no_argument, NULL, 6 }, + {"dhcp-search", no_argument, NULL, 7 }, + {"no-dhcp-search", no_argument, NULL, 8 }, + {"dns-forward", required_argument, NULL, 9 }, { 0 }, }; struct get_bound_ports_ns_arg ns_ports_arg = { .c = c }; @@ -808,6 +824,9 @@ void conf(struct ctx *c, int argc, char **argv) int name, ret, mask, b, i; uint32_t *dns4 = c->dns4; + if (c->mode == MODE_PASTA) + c->no_dhcp_dns = c->no_dhcp_dns_search = 1; + do { enum conf_port_type *set = NULL; const char *optstring; @@ -873,6 +892,51 @@ void conf(struct ctx *c, int argc, char **argv) c->mac_guest[i] = b; } break; + case 5: + if (c->mode != MODE_PASTA) { + err("--dhcp-dns is for pasta mode only"); + usage(argv[0]); + } + c->no_dhcp_dns = 0; + break; + case 6: + if (c->mode != MODE_PASST) { + err("--no-dhcp-dns is for passt mode only"); + usage(argv[0]); + } + c->no_dhcp_dns = 1; + break; + case 7: + if (c->mode != MODE_PASTA) { + err("--dhcp-search is for pasta mode only"); + usage(argv[0]); + } + c->no_dhcp_dns_search = 0; + break; + case 8: + if (c->mode != MODE_PASST) { + err("--no-dhcp-search is for passt mode only"); + usage(argv[0]); + } + c->no_dhcp_dns_search = 1; + break; + case 9: + if (IN6_IS_ADDR_UNSPECIFIED(&c->dns6_fwd) && + inet_pton(AF_INET6, optarg, &c->dns6_fwd) && + !IN6_IS_ADDR_UNSPECIFIED(&c->dns6_fwd) && + !IN6_IS_ADDR_LOOPBACK(&c->dns6_fwd)) + break; + + if (c->dns4_fwd == INADDR_ANY && + inet_pton(AF_INET, optarg, &c->dns4_fwd) && + c->dns4_fwd != INADDR_ANY && + c->dns4_fwd != INADDR_BROADCAST && + c->dns4_fwd != INADDR_LOOPBACK) + break; + + err("Invalid DNS forwarding address: %s", optarg); + usage(argv[0]); + break; case 'd': if (c->debug) { err("Multiple --debug options given"); @@ -1189,10 +1253,6 @@ void conf(struct ctx *c, int argc, char **argv) if (!c->mtu) c->mtu = ROUND_DOWN(ETH_MAX_MTU - ETH_HLEN, sizeof(uint32_t)); - if (c->mode == MODE_PASTA && dns4 == c->dns4 && dns6 == c->dns6) - c->no_dns = 1; - if (c->mode == MODE_PASTA && dnss == c->dns_search) - c->no_dns_search = 1; get_dns(c); if (!*c->pasta_ifn) |