aboutgitcodebugslistschat
diff options
context:
space:
mode:
-rw-r--r--conf.c61
-rw-r--r--dhcp.c10
-rw-r--r--fwd.c4
-rw-r--r--passt.h16
-rw-r--r--pasta.c6
5 files changed, 55 insertions, 42 deletions
diff --git a/conf.c b/conf.c
index 7eec313..d4a3e9c 100644
--- a/conf.c
+++ b/conf.c
@@ -410,12 +410,12 @@ static void add_dns_resolv(struct ctx *c, const char *nameserver,
* redirect
*/
if (IN4_IS_ADDR_LOOPBACK(&ns4)) {
- if (c->no_map_gw)
+ if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.map_host_loopback))
return;
- ns4 = c->ip4.gw;
+ ns4 = c->ip4.map_host_loopback;
if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_match))
- c->ip4.dns_match = c->ip4.gw;
+ c->ip4.dns_match = c->ip4.map_host_loopback;
}
*idx4 += add_dns4(c, &ns4, *idx4);
@@ -429,13 +429,13 @@ static void add_dns_resolv(struct ctx *c, const char *nameserver,
* redirect
*/
if (IN6_IS_ADDR_LOOPBACK(&ns6)) {
- if (c->no_map_gw)
+ if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.map_host_loopback))
return;
- ns6 = c->ip6.gw;
+ ns6 = c->ip6.map_host_loopback;
if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match))
- c->ip6.dns_match = c->ip6.gw;
+ c->ip6.dns_match = c->ip6.map_host_loopback;
}
*idx6 += add_dns6(c, &ns6, *idx6);
@@ -625,8 +625,9 @@ static unsigned int conf_ip4(unsigned int ifi, struct ip4_ctx *ip4)
return 0;
}
- if (IN4_IS_ADDR_UNSPECIFIED(&ip4->gw)) {
- int rc = nl_route_get_def(nl_sock, ifi, AF_INET, &ip4->gw);
+ if (IN4_IS_ADDR_UNSPECIFIED(&ip4->guest_gw)) {
+ int rc = nl_route_get_def(nl_sock, ifi, AF_INET,
+ &ip4->guest_gw);
if (rc < 0) {
err("Couldn't discover IPv4 gateway address: %s",
strerror(-rc));
@@ -658,7 +659,7 @@ static unsigned int conf_ip4(unsigned int ifi, struct ip4_ctx *ip4)
ip4->addr_seen = ip4->addr;
- ip4->our_tap_addr = ip4->gw;
+ ip4->our_tap_addr = ip4->guest_gw;
if (IN4_IS_ADDR_UNSPECIFIED(&ip4->addr))
return 0;
@@ -686,8 +687,8 @@ static unsigned int conf_ip6(unsigned int ifi, struct ip6_ctx *ip6)
return 0;
}
- if (IN6_IS_ADDR_UNSPECIFIED(&ip6->gw)) {
- rc = nl_route_get_def(nl_sock, ifi, AF_INET6, &ip6->gw);
+ if (IN6_IS_ADDR_UNSPECIFIED(&ip6->guest_gw)) {
+ rc = nl_route_get_def(nl_sock, ifi, AF_INET6, &ip6->guest_gw);
if (rc < 0) {
err("Couldn't discover IPv6 gateway address: %s",
strerror(-rc));
@@ -705,8 +706,8 @@ static unsigned int conf_ip6(unsigned int ifi, struct ip6_ctx *ip6)
ip6->addr_seen = ip6->addr;
- if (IN6_IS_ADDR_LINKLOCAL(&ip6->gw))
- ip6->our_tap_ll = ip6->gw;
+ if (IN6_IS_ADDR_LINKLOCAL(&ip6->guest_gw))
+ ip6->our_tap_ll = ip6->guest_gw;
if (IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ||
IN6_IS_ADDR_UNSPECIFIED(&ip6->our_tap_ll))
@@ -969,7 +970,8 @@ static void conf_print(const struct ctx *c)
info(" mask: %s",
inet_ntop(AF_INET, &mask, buf4, sizeof(buf4)));
info(" router: %s",
- inet_ntop(AF_INET, &c->ip4.gw, buf4, sizeof(buf4)));
+ inet_ntop(AF_INET, &c->ip4.guest_gw,
+ buf4, sizeof(buf4)));
}
for (i = 0; !IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns[i]); i++) {
@@ -999,7 +1001,7 @@ static void conf_print(const struct ctx *c)
info(" assign: %s",
inet_ntop(AF_INET6, &c->ip6.addr, buf6, sizeof(buf6)));
info(" router: %s",
- inet_ntop(AF_INET6, &c->ip6.gw, buf6, sizeof(buf6)));
+ inet_ntop(AF_INET6, &c->ip6.guest_gw, buf6, sizeof(buf6)));
info(" our link-local: %s",
inet_ntop(AF_INET6, &c->ip6.our_tap_ll,
buf6, sizeof(buf6)));
@@ -1173,7 +1175,7 @@ fail:
*/
void conf(struct ctx *c, int argc, char **argv)
{
- int netns_only = 0;
+ int netns_only = 0, no_map_gw = 0;
const struct option options[] = {
{"debug", no_argument, NULL, 'd' },
{"quiet", no_argument, NULL, 'q' },
@@ -1202,7 +1204,7 @@ void conf(struct ctx *c, int argc, char **argv)
{"no-dhcpv6", no_argument, &c->no_dhcpv6, 1 },
{"no-ndp", no_argument, &c->no_ndp, 1 },
{"no-ra", no_argument, &c->no_ra, 1 },
- {"no-map-gw", no_argument, &c->no_map_gw, 1 },
+ {"no-map-gw", no_argument, &no_map_gw, 1 },
{"ipv4-only", no_argument, NULL, '4' },
{"ipv6-only", no_argument, NULL, '6' },
{"one-off", no_argument, NULL, '1' },
@@ -1503,18 +1505,18 @@ void conf(struct ctx *c, int argc, char **argv)
parse_mac(c->our_tap_mac, optarg);
break;
case 'g':
- if (inet_pton(AF_INET6, optarg, &c->ip6.gw) &&
- !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.gw) &&
- !IN6_IS_ADDR_LOOPBACK(&c->ip6.gw)) {
+ if (inet_pton(AF_INET6, optarg, &c->ip6.guest_gw) &&
+ !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.guest_gw) &&
+ !IN6_IS_ADDR_LOOPBACK(&c->ip6.guest_gw)) {
if (c->mode == MODE_PASTA)
c->ip6.no_copy_routes = true;
break;
}
- if (inet_pton(AF_INET, optarg, &c->ip4.gw) &&
- !IN4_IS_ADDR_UNSPECIFIED(&c->ip4.gw) &&
- !IN4_IS_ADDR_BROADCAST(&c->ip4.gw) &&
- !IN4_IS_ADDR_LOOPBACK(&c->ip4.gw)) {
+ if (inet_pton(AF_INET, optarg, &c->ip4.guest_gw) &&
+ !IN4_IS_ADDR_UNSPECIFIED(&c->ip4.guest_gw) &&
+ !IN4_IS_ADDR_BROADCAST(&c->ip4.guest_gw) &&
+ !IN4_IS_ADDR_LOOPBACK(&c->ip4.guest_gw)) {
if (c->mode == MODE_PASTA)
c->ip4.no_copy_routes = true;
break;
@@ -1637,11 +1639,14 @@ void conf(struct ctx *c, int argc, char **argv)
(*c->ip6.ifname_out && !c->ifi6))
die("External interface not usable");
- if (c->ifi4 && IN4_IS_ADDR_UNSPECIFIED(&c->ip4.gw))
- c->no_map_gw = c->no_dhcp = 1;
+ if (c->ifi4 && !no_map_gw)
+ c->ip4.map_host_loopback = c->ip4.guest_gw;
- if (c->ifi6 && IN6_IS_ADDR_UNSPECIFIED(&c->ip6.gw))
- c->no_map_gw = 1;
+ if (c->ifi6 && !no_map_gw)
+ c->ip6.map_host_loopback = c->ip6.guest_gw;
+
+ if (c->ifi4 && IN4_IS_ADDR_UNSPECIFIED(&c->ip4.guest_gw))
+ c->no_dhcp = 1;
/* Inbound port options & DNS can be parsed now (after IPv4/IPv6
* settings)
diff --git a/dhcp.c b/dhcp.c
index 353de32..a06f143 100644
--- a/dhcp.c
+++ b/dhcp.c
@@ -346,19 +346,21 @@ int dhcp(const struct ctx *c, const struct pool *p)
m->yiaddr = c->ip4.addr;
mask.s_addr = htonl(0xffffffff << (32 - c->ip4.prefix_len));
memcpy(opts[1].s, &mask, sizeof(mask));
- memcpy(opts[3].s, &c->ip4.gw, sizeof(c->ip4.gw));
+ memcpy(opts[3].s, &c->ip4.guest_gw, sizeof(c->ip4.guest_gw));
memcpy(opts[54].s, &c->ip4.our_tap_addr, sizeof(c->ip4.our_tap_addr));
/* If the gateway is not on the assigned subnet, send an option 121
* (Classless Static Routing) adding a dummy route to it.
*/
if ((c->ip4.addr.s_addr & mask.s_addr)
- != (c->ip4.gw.s_addr & mask.s_addr)) {
+ != (c->ip4.guest_gw.s_addr & mask.s_addr)) {
/* a.b.c.d/32:0.0.0.0, 0:a.b.c.d */
opts[121].slen = 14;
opts[121].s[0] = 32;
- memcpy(opts[121].s + 1, &c->ip4.gw, sizeof(c->ip4.gw));
- memcpy(opts[121].s + 10, &c->ip4.gw, sizeof(c->ip4.gw));
+ memcpy(opts[121].s + 1,
+ &c->ip4.guest_gw, sizeof(c->ip4.guest_gw));
+ memcpy(opts[121].s + 10,
+ &c->ip4.guest_gw, sizeof(c->ip4.guest_gw));
}
if (c->mtu != -1) {
diff --git a/fwd.c b/fwd.c
index 664b8ac..f99d204 100644
--- a/fwd.c
+++ b/fwd.c
@@ -268,9 +268,9 @@ uint8_t fwd_nat_from_tap(const struct ctx *c, uint8_t proto,
else if (is_dns_flow(proto, ini) &&
inany_equals6(&ini->oaddr, &c->ip6.dns_match))
tgt->eaddr.a6 = c->ip6.dns_host;
- else if (!c->no_map_gw && inany_equals4(&ini->oaddr, &c->ip4.gw))
+ else if (inany_equals4(&ini->oaddr, &c->ip4.map_host_loopback))
tgt->eaddr = inany_loopback4;
- else if (!c->no_map_gw && inany_equals6(&ini->oaddr, &c->ip6.gw))
+ else if (inany_equals6(&ini->oaddr, &c->ip6.map_host_loopback))
tgt->eaddr = inany_loopback6;
else
tgt->eaddr = ini->oaddr;
diff --git a/passt.h b/passt.h
index c6c67ff..7cdba85 100644
--- a/passt.h
+++ b/passt.h
@@ -101,7 +101,9 @@ enum passt_modes {
* @addr: IPv4 address assigned to guest
* @addr_seen: Latest IPv4 address seen as source from tap
* @prefixlen: IPv4 prefix length (netmask)
- * @gw: Default IPv4 gateway
+ * @guest_gw: IPv4 gateway as seen by the guest
+ * @map_host_loopback: Outbound connections to this address are NATted to the
+ * host's 127.0.0.1
* @dns: DNS addresses for DHCP, zero-terminated
* @dns_match: Forward DNS query if sent to this address
* @our_tap_addr: IPv4 address for passt's use on tap
@@ -116,7 +118,8 @@ struct ip4_ctx {
struct in_addr addr;
struct in_addr addr_seen;
int prefix_len;
- struct in_addr gw;
+ struct in_addr guest_gw;
+ struct in_addr map_host_loopback;
struct in_addr dns[MAXNS + 1];
struct in_addr dns_match;
struct in_addr our_tap_addr;
@@ -136,7 +139,9 @@ struct ip4_ctx {
* @addr: IPv6 address assigned to guest
* @addr_seen: Latest IPv6 global/site address seen as source from tap
* @addr_ll_seen: Latest IPv6 link-local address seen as source from tap
- * @gw: Default IPv6 gateway
+ * @guest_gw: IPv6 gateway as seen by the guest
+ * @map_host_loopback: Outbound connections to this address are NATted to the
+ * host's [::1]
* @dns: DNS addresses for DHCPv6 and NDP, zero-terminated
* @dns_match: Forward DNS query if sent to this address
* @our_tap_ll: Link-local IPv6 address for passt's use on tap
@@ -151,7 +156,8 @@ struct ip6_ctx {
struct in6_addr addr;
struct in6_addr addr_seen;
struct in6_addr addr_ll_seen;
- struct in6_addr gw;
+ struct in6_addr guest_gw;
+ struct in6_addr map_host_loopback;
struct in6_addr dns[MAXNS + 1];
struct in6_addr dns_match;
struct in6_addr our_tap_ll;
@@ -213,7 +219,6 @@ struct ip6_ctx {
* @no_dhcpv6: Disable DHCPv6 server
* @no_ndp: Disable NDP handler altogether
* @no_ra: Disable router advertisements
- * @no_map_gw: Don't map connections, untracked UDP to gateway to host
* @low_wmem: Low probed net.core.wmem_max
* @low_rmem: Low probed net.core.rmem_max
*/
@@ -273,7 +278,6 @@ struct ctx {
int no_dhcpv6;
int no_ndp;
int no_ra;
- int no_map_gw;
int low_wmem;
int low_rmem;
diff --git a/pasta.c b/pasta.c
index 5f897d3..0df7cb4 100644
--- a/pasta.c
+++ b/pasta.c
@@ -332,7 +332,8 @@ void pasta_ns_conf(struct ctx *c)
if (c->ip4.no_copy_routes) {
rc = nl_route_set_def(nl_sock_ns, c->pasta_ifi,
- AF_INET, &c->ip4.gw);
+ AF_INET,
+ &c->ip4.guest_gw);
} else {
rc = nl_route_dup(nl_sock, c->ifi4, nl_sock_ns,
c->pasta_ifi, AF_INET);
@@ -378,7 +379,8 @@ void pasta_ns_conf(struct ctx *c)
if (c->ip6.no_copy_routes) {
rc = nl_route_set_def(nl_sock_ns, c->pasta_ifi,
- AF_INET6, &c->ip6.gw);
+ AF_INET6,
+ &c->ip6.guest_gw);
} else {
rc = nl_route_dup(nl_sock, c->ifi6,
nl_sock_ns, c->pasta_ifi,