diff --git a/dhcp.c b/dhcp.c index acc5b03..353de32 100644 --- a/dhcp.c +++ b/dhcp.c @@ -345,9 +345,9 @@ 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[54].s, &c->ip4.gw, sizeof(c->ip4.gw)); + memcpy(opts[1].s, &mask, sizeof(mask)); + memcpy(opts[3].s, &c->ip4.gw, sizeof(c->ip4.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. @@ -377,7 +377,7 @@ int dhcp(const struct ctx *c, const struct pool *p) opt_set_dns_search(c, sizeof(m->o)); dlen = offsetof(struct msg, o) + fill(m); - tap_udp4_send(c, c->ip4.gw, 67, c->ip4.addr, 68, m, dlen); + tap_udp4_send(c, c->ip4.our_tap_addr, 67, c->ip4.addr, 68, m, dlen); return 1; } diff --git a/fwd.c b/fwd.c index d6f8a23..664b8ac 100644 --- a/fwd.c +++ b/fwd.c @@ -387,10 +387,14 @@ uint8_t fwd_nat_from_host(const struct ctx *c, uint8_t proto, } if (!fwd_guest_accessible(c, &ini->eaddr)) { - if (inany_v4(&ini->eaddr)) - tgt->oaddr = inany_from_v4(c->ip4.gw); - else + if (inany_v4(&ini->eaddr)) { + if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.our_tap_addr)) + /* No source address we can use */ + return PIF_NONE; + tgt->oaddr = inany_from_v4(c->ip4.our_tap_addr); + } else { tgt->oaddr.a6 = c->ip6.our_tap_ll; + } } else { tgt->oaddr = ini->eaddr; } diff --git a/passt.h b/passt.h index 3b8a628..ecfed1e 100644 --- a/passt.h +++ b/passt.h @@ -97,6 +97,7 @@ enum passt_modes { * @gw: Default IPv4 gateway * @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 * @dns_host: Use this DNS on the host for forwarding * @addr_out: Optional source address for outbound traffic * @ifname_out: Optional interface name to bind outbound sockets to @@ -111,6 +112,7 @@ struct ip4_ctx { struct in_addr gw; struct in_addr dns[MAXNS + 1]; struct in_addr dns_match; + struct in_addr our_tap_addr; /* PIF_HOST addresses */ struct in_addr dns_host;