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>
This commit is contained in:
parent
01ae772dcc
commit
89678c5157
8 changed files with 177 additions and 38 deletions
90
conf.c
90
conf.c
|
@ -279,7 +279,7 @@ static void get_dns(struct ctx *c)
|
||||||
dns4_set = !c->v4 || !!*dns4;
|
dns4_set = !c->v4 || !!*dns4;
|
||||||
dns6_set = !c->v6 || !IN6_IS_ADDR_UNSPECIFIED(dns6);
|
dns6_set = !c->v6 || !IN6_IS_ADDR_UNSPECIFIED(dns6);
|
||||||
dnss_set = !!*s->n || c->no_dns_search;
|
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)
|
if (dns_set && dnss_set)
|
||||||
return;
|
return;
|
||||||
|
@ -583,21 +583,35 @@ static void usage(const char *name)
|
||||||
info( " default: gateway from interface with default route");
|
info( " default: gateway from interface with default route");
|
||||||
info( " -i, --interface NAME Interface for addresses and routes");
|
info( " -i, --interface NAME Interface for addresses and routes");
|
||||||
info( " default: interface with first default route");
|
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( " can be specified multiple times");
|
||||||
info( " a single, empty option disables DNS information");
|
info( " a single, empty option disables DNS information");
|
||||||
if (strstr(name, "pasta"))
|
if (strstr(name, "pasta"))
|
||||||
info( " default: don't send any addresses");
|
info( " default: don't use any addresses");
|
||||||
else
|
else
|
||||||
info( " default: use addresses from /etc/resolv.conf");
|
info( " default: use addresses from /etc/resolv.conf");
|
||||||
|
|
||||||
info( " -S, --search LIST Space-separated list, search domains");
|
info( " -S, --search LIST Space-separated list, search domains");
|
||||||
info( " a single, empty option disables the DNS search list");
|
info( " a single, empty option disables the DNS search list");
|
||||||
if (strstr(name, "pasta"))
|
if (strstr(name, "pasta"))
|
||||||
info( " default: don't send any search list");
|
info( " default: don't use any search list");
|
||||||
else
|
else
|
||||||
info( " default: use search list from /etc/resolv.conf");
|
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-tcp Disable TCP protocol handler");
|
||||||
info( " --no-udp Disable UDP protocol handler");
|
info( " --no-udp Disable UDP protocol handler");
|
||||||
info( " --no-icmp Disable ICMP/ICMPv6 protocol handler");
|
info( " --no-icmp Disable ICMP/ICMPv6 protocol handler");
|
||||||
|
@ -699,21 +713,17 @@ void conf_print(struct ctx *c)
|
||||||
info(" router: %s",
|
info(" router: %s",
|
||||||
inet_ntop(AF_INET, &c->gw4, buf4, sizeof(buf4)));
|
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++) {
|
for (i = 0; c->dns4[i]; i++) {
|
||||||
if (!i)
|
if (!i)
|
||||||
info("DNS:");
|
info("DNS:");
|
||||||
inet_ntop(AF_INET, &c->dns4[i], buf4, sizeof(buf4));
|
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++) {
|
for (i = 0; *c->dns_search[i].n; i++) {
|
||||||
if (!i)
|
if (!i)
|
||||||
info(" search:");
|
info("DNS search list:");
|
||||||
info(" %s", c->dns_search[i].n);
|
info(" %s", c->dns_search[i].n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -728,7 +738,7 @@ void conf_print(struct ctx *c)
|
||||||
else if (!c->no_dhcpv6)
|
else if (!c->no_dhcpv6)
|
||||||
info("NDP:");
|
info("NDP:");
|
||||||
else
|
else
|
||||||
return;
|
goto dns6;
|
||||||
|
|
||||||
info(" assign: %s",
|
info(" assign: %s",
|
||||||
inet_ntop(AF_INET6, &c->addr6, buf6, sizeof(buf6)));
|
inet_ntop(AF_INET6, &c->addr6, buf6, sizeof(buf6)));
|
||||||
|
@ -737,6 +747,7 @@ void conf_print(struct ctx *c)
|
||||||
info(" our link-local: %s",
|
info(" our link-local: %s",
|
||||||
inet_ntop(AF_INET6, &c->addr6_ll, buf6, sizeof(buf6)));
|
inet_ntop(AF_INET6, &c->addr6_ll, buf6, sizeof(buf6)));
|
||||||
|
|
||||||
|
dns6:
|
||||||
for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[i]); i++) {
|
for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[i]); i++) {
|
||||||
if (!i)
|
if (!i)
|
||||||
info("DNS:");
|
info("DNS:");
|
||||||
|
@ -746,7 +757,7 @@ void conf_print(struct ctx *c)
|
||||||
|
|
||||||
for (i = 0; *c->dns_search[i].n; i++) {
|
for (i = 0; *c->dns_search[i].n; i++) {
|
||||||
if (!i)
|
if (!i)
|
||||||
info(" search:");
|
info("DNS search list:");
|
||||||
info(" %s", c->dns_search[i].n);
|
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 },
|
{"nsrun-dir", required_argument, NULL, 3 },
|
||||||
{"config-net", no_argument, &c->pasta_conf_ns, 1 },
|
{"config-net", no_argument, &c->pasta_conf_ns, 1 },
|
||||||
{"ns-mac-addr", required_argument, NULL, 4 },
|
{"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 },
|
{ 0 },
|
||||||
};
|
};
|
||||||
struct get_bound_ports_ns_arg ns_ports_arg = { .c = c };
|
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;
|
int name, ret, mask, b, i;
|
||||||
uint32_t *dns4 = c->dns4;
|
uint32_t *dns4 = c->dns4;
|
||||||
|
|
||||||
|
if (c->mode == MODE_PASTA)
|
||||||
|
c->no_dhcp_dns = c->no_dhcp_dns_search = 1;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
enum conf_port_type *set = NULL;
|
enum conf_port_type *set = NULL;
|
||||||
const char *optstring;
|
const char *optstring;
|
||||||
|
@ -873,6 +892,51 @@ void conf(struct ctx *c, int argc, char **argv)
|
||||||
c->mac_guest[i] = b;
|
c->mac_guest[i] = b;
|
||||||
}
|
}
|
||||||
break;
|
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':
|
case 'd':
|
||||||
if (c->debug) {
|
if (c->debug) {
|
||||||
err("Multiple --debug options given");
|
err("Multiple --debug options given");
|
||||||
|
@ -1189,10 +1253,6 @@ void conf(struct ctx *c, int argc, char **argv)
|
||||||
if (!c->mtu)
|
if (!c->mtu)
|
||||||
c->mtu = ROUND_DOWN(ETH_MAX_MTU - ETH_HLEN, sizeof(uint32_t));
|
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);
|
get_dns(c);
|
||||||
|
|
||||||
if (!*c->pasta_ifn)
|
if (!*c->pasta_ifn)
|
||||||
|
|
3
dhcp.c
3
dhcp.c
|
@ -333,11 +333,12 @@ int dhcp(struct ctx *c, struct ethhdr *eh, size_t len)
|
||||||
opts[26].s[1] = c->mtu % 256;
|
opts[26].s[1] = c->mtu % 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0, opts[6].slen = 0; c->dns4[i]; i++) {
|
for (i = 0, opts[6].slen = 0; !c->no_dhcp_dns && c->dns4[i]; i++) {
|
||||||
((uint32_t *)opts[6].s)[i] = c->dns4[i];
|
((uint32_t *)opts[6].s)[i] = c->dns4[i];
|
||||||
opts[6].slen += sizeof(uint32_t);
|
opts[6].slen += sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!c->no_dhcp_dns_search)
|
||||||
opt_set_dns_search(c, sizeof(m->o));
|
opt_set_dns_search(c, sizeof(m->o));
|
||||||
|
|
||||||
uh->len = htons(len = offsetof(struct msg, o) + fill(m) + sizeof(*uh));
|
uh->len = htons(len = offsetof(struct msg, o) + fill(m) + sizeof(*uh));
|
||||||
|
|
7
dhcpv6.c
7
dhcpv6.c
|
@ -394,6 +394,9 @@ static size_t dhcpv6_dns_fill(struct ctx *c, char *buf, int offset)
|
||||||
char *p = NULL;
|
char *p = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (c->no_dhcp_dns)
|
||||||
|
goto search;
|
||||||
|
|
||||||
for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[i]); i++) {
|
for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[i]); i++) {
|
||||||
if (!i) {
|
if (!i) {
|
||||||
srv = (struct opt_dns_servers *)(buf + offset);
|
srv = (struct opt_dns_servers *)(buf + offset);
|
||||||
|
@ -410,6 +413,10 @@ static size_t dhcpv6_dns_fill(struct ctx *c, char *buf, int offset)
|
||||||
if (srv)
|
if (srv)
|
||||||
srv->hdr.l = htons(srv->hdr.l);
|
srv->hdr.l = htons(srv->hdr.l);
|
||||||
|
|
||||||
|
search:
|
||||||
|
if (c->no_dhcp_dns_search)
|
||||||
|
return offset;
|
||||||
|
|
||||||
for (i = 0; *c->dns_search[i].n; i++) {
|
for (i = 0; *c->dns_search[i].n; i++) {
|
||||||
if (!i) {
|
if (!i) {
|
||||||
srch = (struct opt_dns_search *)(buf + offset);
|
srch = (struct opt_dns_search *)(buf + offset);
|
||||||
|
|
6
ndp.c
6
ndp.c
|
@ -127,6 +127,9 @@ int ndp(struct ctx *c, struct ethhdr *eh, size_t len)
|
||||||
p += 4;
|
p += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->no_dhcp_dns)
|
||||||
|
goto dns_done;
|
||||||
|
|
||||||
for (n = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[n]); n++);
|
for (n = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->dns6[n]); n++);
|
||||||
if (n) {
|
if (n) {
|
||||||
*p++ = 25; /* RDNSS */
|
*p++ = 25; /* RDNSS */
|
||||||
|
@ -144,7 +147,7 @@ int ndp(struct ctx *c, struct ethhdr *eh, size_t len)
|
||||||
dns_s_len += strlen(c->dns_search[n].n) + 2;
|
dns_s_len += strlen(c->dns_search[n].n) + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dns_s_len) {
|
if (!c->no_dhcp_dns_search && dns_s_len) {
|
||||||
*p++ = 31; /* DNSSL */
|
*p++ = 31; /* DNSSL */
|
||||||
*p++ = (len + 8 - 1) / 8 + 1; /* length */
|
*p++ = (len + 8 - 1) / 8 + 1; /* length */
|
||||||
p += 2; /* reserved */
|
p += 2; /* reserved */
|
||||||
|
@ -171,6 +174,7 @@ int ndp(struct ctx *c, struct ethhdr *eh, size_t len)
|
||||||
p += 8 - dns_s_len % 8;
|
p += 8 - dns_s_len % 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dns_done:
|
||||||
*p++ = 1; /* source ll */
|
*p++ = 1; /* source ll */
|
||||||
*p++ = 1; /* length */
|
*p++ = 1; /* length */
|
||||||
memcpy(p, c->mac, ETH_ALEN);
|
memcpy(p, c->mac, ETH_ALEN);
|
||||||
|
|
63
passt.1
63
passt.1
|
@ -165,19 +165,62 @@ Default is to use the interface with the first default route.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BR \-D ", " \-\-dns " " \fIaddr
|
.BR \-D ", " \-\-dns " " \fIaddr
|
||||||
Assign IPv4 \fIaddr\fR via DHCP (option 23) or IPv6 \fIaddr\fR via NDP Router
|
Use \fIaddr\fR (IPv4 or IPv6) for DHCP, DHCPv6, NDP or DNS forwarding, as
|
||||||
Advertisement (option type 25) and DHCPv6 (option 23) as DNS resolver.
|
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, and a single, empty option disables
|
This option can be specified multiple times, and a single, empty option disables
|
||||||
DNS options altogether.
|
usage of DNS addresses altogether.
|
||||||
In \fBpasst\fR mode, default is to use addresses from \fI/etc/resolv.conf\fR,
|
|
||||||
and, in \fBpasta\fR mode, no addresses are sent by default.
|
.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, and a single, empty option disables
|
||||||
|
usage of DNS addresses altogether.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR \-\-dns-forward " " \fIaddr
|
||||||
|
Map \fIaddr\fR (IPv4 or IPv6) as seen from guest or namespace to the first
|
||||||
|
configured DNS resolver (with corresponding IP version). Mapping is limited to
|
||||||
|
UDP traffic directed to port 53, and DNS answers are translated back with a
|
||||||
|
reverse mapping.
|
||||||
|
This option can be specified zero to two times (once for IPv4, once for IPv6).
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BR \-S ", " \-\-search " " \fIlist
|
.BR \-S ", " \-\-search " " \fIlist
|
||||||
Assign space-separated \fIlist\fR via DHCP (option 119), via NDP Router
|
Use space-separated \fIlist\fR for DHCP, DHCPv6, and NDP purposes, instead of
|
||||||
Advertisement (option type 31) and DHCPv6 (option 24) as DNS domain search list.
|
reading entries from \fI/etc/resolv.conf\fR. See options \fB--no-dhcp-search\fR
|
||||||
A single, empty option disables sending the DNS domain search list.
|
and \fB--dhcp-search\fR. A single, empty option disables the DNS domain search
|
||||||
In \fBpasst\fR mode, default is to use the search list from
|
list altogether.
|
||||||
\fI/etc/resolv.conf\fR, and, in \fBpasta\fR mode, no list is sent by default.
|
|
||||||
|
.TP
|
||||||
|
.BR \-\-no-dhcp-dns " " \fIaddr
|
||||||
|
In \fIpasst\fR mode, do not assign IPv4 addresses via DHCP (option 23) or IPv6
|
||||||
|
addresses via NDP Router Advertisement (option type 25) and DHCPv6 (option 23)
|
||||||
|
as DNS resolvers.
|
||||||
|
By default, all the configured addresses are passed.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR \-\-dhcp-dns " " \fIaddr
|
||||||
|
In \fIpasta\fR mode, assign IPv4 addresses via DHCP (option 23) or IPv6
|
||||||
|
addresses via NDP Router Advertisement (option type 25) and DHCPv6 (option 23)
|
||||||
|
as DNS resolvers.
|
||||||
|
By default, configured addresses, if any, are not passed.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR \-\-no-dhcp-search " " \fIaddr
|
||||||
|
In \fIpasst\fR mode, do not send the DNS domain search list addresses via DHCP
|
||||||
|
(option 119), via NDP Router Advertisement (option type 31) and DHCPv6 (option
|
||||||
|
24).
|
||||||
|
By default, the DNS domain search list resulting from configuration is passed.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR \-\-dhcp-search " " \fIaddr
|
||||||
|
In \fIpasta\fR mode, send the DNS domain search list addresses via DHCP (option
|
||||||
|
119), via NDP Router Advertisement (option type 31) and DHCPv6 (option 24).
|
||||||
|
By default, the DNS domain search list resulting from configuration is not
|
||||||
|
passed.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BR \-\-no-tcp
|
.BR \-\-no-tcp
|
||||||
|
|
14
passt.h
14
passt.h
|
@ -114,6 +114,7 @@ enum passt_modes {
|
||||||
* @mask4: IPv4 netmask, network order
|
* @mask4: IPv4 netmask, network order
|
||||||
* @gw4: Default IPv4 gateway, network order
|
* @gw4: Default IPv4 gateway, network order
|
||||||
* @dns4: IPv4 DNS addresses, zero-terminated, network order
|
* @dns4: IPv4 DNS addresses, zero-terminated, network order
|
||||||
|
* @dns4_fwd: Address forwarded (UDP) to first IPv4 DNS, network order
|
||||||
* @dns_search: DNS search list
|
* @dns_search: DNS search list
|
||||||
* @v6: Enable IPv6 transport
|
* @v6: Enable IPv6 transport
|
||||||
* @addr6: IPv6 address for external, routable interface
|
* @addr6: IPv6 address for external, routable interface
|
||||||
|
@ -121,7 +122,8 @@ enum passt_modes {
|
||||||
* @addr6_seen: Latest IPv6 global/site address seen as source from tap
|
* @addr6_seen: Latest IPv6 global/site address seen as source from tap
|
||||||
* @addr6_ll_seen: Latest IPv6 link-local address seen as source from tap
|
* @addr6_ll_seen: Latest IPv6 link-local address seen as source from tap
|
||||||
* @gw6: Default IPv6 gateway
|
* @gw6: Default IPv6 gateway
|
||||||
* @dns4: IPv4 DNS addresses, zero-terminated
|
* @dns6: IPv6 DNS addresses, zero-terminated
|
||||||
|
* @dns6_fwd: Address forwarded (UDP) to first IPv6 DNS, network order
|
||||||
* @ifi: Index of routable interface
|
* @ifi: Index of routable interface
|
||||||
* @pasta_ifn: Name of namespace interface for pasta
|
* @pasta_ifn: Name of namespace interface for pasta
|
||||||
* @pasta_ifn: Index of namespace interface for pasta
|
* @pasta_ifn: Index of namespace interface for pasta
|
||||||
|
@ -133,8 +135,10 @@ enum passt_modes {
|
||||||
* @no_icmp: Disable ICMP operation
|
* @no_icmp: Disable ICMP operation
|
||||||
* @icmp: Context for ICMP protocol handler
|
* @icmp: Context for ICMP protocol handler
|
||||||
* @mtu: MTU passed via DHCP/NDP
|
* @mtu: MTU passed via DHCP/NDP
|
||||||
* @no_dns: Do not assign any DNS server via DHCP/DHCPv6/NDP
|
* @no_dns: Do not source/use DNS servers for any purpose
|
||||||
* @no_dns_search: Do not assign any DNS domain search via DHCP/DHCPv6/NDP
|
* @no_dns_search: Do not source/use domain search lists for any purpose
|
||||||
|
* @no_dhcp_dns: Do not assign any DNS server via DHCP/DHCPv6/NDP
|
||||||
|
* @no_dhcp_dns_search: Do not assign any DNS domain search via DHCP/DHCPv6/NDP
|
||||||
* @no_dhcp: Disable DHCP server
|
* @no_dhcp: Disable DHCP server
|
||||||
* @no_dhcpv6: Disable DHCPv6 server
|
* @no_dhcpv6: Disable DHCPv6 server
|
||||||
* @no_ndp: Disable NDP handler altogether
|
* @no_ndp: Disable NDP handler altogether
|
||||||
|
@ -172,6 +176,7 @@ struct ctx {
|
||||||
uint32_t mask4;
|
uint32_t mask4;
|
||||||
uint32_t gw4;
|
uint32_t gw4;
|
||||||
uint32_t dns4[MAXNS + 1];
|
uint32_t dns4[MAXNS + 1];
|
||||||
|
uint32_t dns4_fwd;
|
||||||
|
|
||||||
struct fqdn dns_search[MAXDNSRCH];
|
struct fqdn dns_search[MAXDNSRCH];
|
||||||
|
|
||||||
|
@ -182,6 +187,7 @@ struct ctx {
|
||||||
struct in6_addr addr6_ll_seen;
|
struct in6_addr addr6_ll_seen;
|
||||||
struct in6_addr gw6;
|
struct in6_addr gw6;
|
||||||
struct in6_addr dns6[MAXNS + 1];
|
struct in6_addr dns6[MAXNS + 1];
|
||||||
|
struct in6_addr dns6_fwd;
|
||||||
|
|
||||||
unsigned int ifi;
|
unsigned int ifi;
|
||||||
char pasta_ifn[IF_NAMESIZE];
|
char pasta_ifn[IF_NAMESIZE];
|
||||||
|
@ -198,6 +204,8 @@ struct ctx {
|
||||||
int mtu;
|
int mtu;
|
||||||
int no_dns;
|
int no_dns;
|
||||||
int no_dns_search;
|
int no_dns_search;
|
||||||
|
int no_dhcp_dns;
|
||||||
|
int no_dhcp_dns_search;
|
||||||
int no_dhcp;
|
int no_dhcp;
|
||||||
int no_dhcpv6;
|
int no_dhcpv6;
|
||||||
int no_ndp;
|
int no_ndp;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||||
|
|
||||||
PASTA_PID="$(mktemp)"
|
PASTA_PID="$(mktemp)"
|
||||||
PASTA_OPTS="-q --ipv4-only -a 10.0.2.0 -n 24 -g 10.0.2.2 -m 1500 --no-ndp --no-dhcpv6 --no-dhcp -P ${PASTA_PID}"
|
PASTA_OPTS="-q --ipv4-only -a 10.0.2.0 -n 24 -g 10.0.2.2 --dns-forward 10.0.2.3 -m 1500 --no-ndp --no-dhcpv6 --no-dhcp -P ${PASTA_PID}"
|
||||||
PASTA="$(command -v ./pasta || command -v pasta || :)"
|
PASTA="$(command -v ./pasta || command -v pasta || :)"
|
||||||
|
|
||||||
API_SOCKET=
|
API_SOCKET=
|
||||||
|
|
16
udp.c
16
udp.c
|
@ -718,6 +718,12 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events,
|
||||||
udp_tap_map[V6][src].loopback = 0;
|
udp_tap_map[V6][src].loopback = 0;
|
||||||
|
|
||||||
bitmap_set(udp_act[V6][UDP_ACT_TAP], src);
|
bitmap_set(udp_act[V6][UDP_ACT_TAP], src);
|
||||||
|
} else if (!IN6_IS_ADDR_UNSPECIFIED(&c->dns6_fwd) &&
|
||||||
|
!memcmp(&b->s_in6.sin6_addr, &c->dns6_fwd,
|
||||||
|
sizeof(c->dns6_fwd)) &&
|
||||||
|
ntohs(b->s_in6.sin6_port) == 53) {
|
||||||
|
b->ip6h.daddr = c->addr6_seen;
|
||||||
|
b->ip6h.saddr = c->dns6_fwd;
|
||||||
} else {
|
} else {
|
||||||
b->ip6h.daddr = c->addr6_seen;
|
b->ip6h.daddr = c->addr6_seen;
|
||||||
b->ip6h.saddr = b->s_in6.sin6_addr;
|
b->ip6h.saddr = b->s_in6.sin6_addr;
|
||||||
|
@ -797,6 +803,10 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events,
|
||||||
udp_tap_map[V4][src].loopback = 1;
|
udp_tap_map[V4][src].loopback = 1;
|
||||||
|
|
||||||
bitmap_set(udp_act[V4][UDP_ACT_TAP], src);
|
bitmap_set(udp_act[V4][UDP_ACT_TAP], src);
|
||||||
|
} else if (c->dns4_fwd &&
|
||||||
|
s_addr == ntohl(c->dns4[0]) &&
|
||||||
|
ntohs(b->s_in.sin_port) == 53) {
|
||||||
|
b->iph.saddr = c->dns4_fwd;
|
||||||
} else {
|
} else {
|
||||||
b->iph.saddr = b->s_in.sin_addr.s_addr;
|
b->iph.saddr = b->s_in.sin_addr.s_addr;
|
||||||
}
|
}
|
||||||
|
@ -958,6 +968,9 @@ int udp_tap_handler(struct ctx *c, int af, void *addr,
|
||||||
s_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
s_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
else
|
else
|
||||||
s_in.sin_addr.s_addr = c->addr4_seen;
|
s_in.sin_addr.s_addr = c->addr4_seen;
|
||||||
|
} else if (s_in.sin_addr.s_addr == c->dns4_fwd &&
|
||||||
|
ntohs(s_in.sin_port) == 53) {
|
||||||
|
s_in.sin_addr.s_addr = c->dns4[0];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s_in6 = (struct sockaddr_in6) {
|
s_in6 = (struct sockaddr_in6) {
|
||||||
|
@ -976,6 +989,9 @@ int udp_tap_handler(struct ctx *c, int af, void *addr,
|
||||||
s_in6.sin6_addr = in6addr_loopback;
|
s_in6.sin6_addr = in6addr_loopback;
|
||||||
else
|
else
|
||||||
s_in6.sin6_addr = c->addr6_seen;
|
s_in6.sin6_addr = c->addr6_seen;
|
||||||
|
} else if (!memcmp(addr, &c->dns6_fwd, sizeof(c->dns6_fwd)) &&
|
||||||
|
ntohs(s_in6.sin6_port) == 53) {
|
||||||
|
s_in6.sin6_addr = c->dns6[0];
|
||||||
} else if (IN6_IS_ADDR_LINKLOCAL(&s_in6.sin6_addr)) {
|
} else if (IN6_IS_ADDR_LINKLOCAL(&s_in6.sin6_addr)) {
|
||||||
bind_to = BIND_LL;
|
bind_to = BIND_LL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue