public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: Stefano Brivio <sbrivio@redhat.com>, passt-dev@passt.top
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH 4/7] nat: Simplify --no-map-gw handling
Date: Mon,  1 May 2023 21:06:59 +1000	[thread overview]
Message-ID: <20230501110702.3915529-5-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20230501110702.3915529-1-david@gibson.dropbear.id.au>

Currently, most places we use c->ip[46].nattohost we also need to
check c->no_map_gw to see if we should even be applying this address
remapping.  However, now that the remapping address is split into its
own field we can just use the unspecified address to indicate no
remapping, and avoid the extra flag.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 conf.c  | 35 +++++++++++++++++++++--------------
 passt.h |  2 --
 tcp.c   | 10 ++++------
 udp.c   |  6 ++----
 4 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/conf.c b/conf.c
index bfc825b..dd8a835 100644
--- a/conf.c
+++ b/conf.c
@@ -418,12 +418,13 @@ static void add_dns4(struct ctx *c, struct in_addr *addr, struct in_addr **conf)
 {
 	/* Guest or container can only access local addresses via redirect */
 	if (IN4_IS_ADDR_LOOPBACK(addr)) {
-		if (!c->no_map_gw) {
-			**conf = c->ip4.nattohost;
+		const struct in_addr *nat = &c->ip4.nattohost;
+		if (!IN4_IS_ADDR_UNSPECIFIED(nat)) {
+			**conf = *nat;
 			(*conf)++;
 
 			if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_match))
-				c->ip4.dns_match = c->ip4.nattohost;
+				c->ip4.dns_match = *nat;
 		}
 	} else {
 		**conf = *addr;
@@ -445,8 +446,9 @@ static void add_dns6(struct ctx *c,
 {
 	/* Guest or container can only access local addresses via redirect */
 	if (IN6_IS_ADDR_LOOPBACK(addr)) {
-		if (!c->no_map_gw) {
-			memcpy(*conf, &c->ip6.nattohost, sizeof(**conf));
+		const struct in6_addr *nat = &c->ip6.nattohost;
+		if (!IN6_IS_ADDR_UNSPECIFIED(nat)) {
+			memcpy(*conf, nat, sizeof(**conf));
 			(*conf)++;
 
 			if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match))
@@ -628,11 +630,12 @@ static int conf_ip4_prefix(const char *arg)
  * @ifi:	Host interface to attempt (0 to determine one)
  * @ip4:	IPv4 context (will be written)
  * @mac:	MAC address to use (written if unset)
+ * @gwnat:	If set, use gateway as default nattohost address
  *
  * Return:	Interface index for IPv4, or 0 on failure.
  */
-static unsigned int conf_ip4(unsigned int ifi,
-			     struct ip4_ctx *ip4, unsigned char *mac)
+static unsigned int conf_ip4(unsigned int ifi, struct ip4_ctx *ip4,
+			     unsigned char *mac, bool gwnat)
 {
 	in_addr_t addr, gw;
 	int shift;
@@ -688,7 +691,8 @@ static unsigned int conf_ip4(unsigned int ifi,
 	if (MAC_IS_ZERO(mac))
 		nl_link(0, ifi, mac, 0, 0);
 
-	ip4->nattohost = ip4->router;
+	if (gwnat && IN4_IS_ADDR_UNSPECIFIED(&ip4->nattohost))
+		ip4->nattohost = ip4->router;
 
 	if (IN4_IS_ADDR_UNSPECIFIED(&ip4->router) ||
 	    IN4_IS_ADDR_UNSPECIFIED(&ip4->addr) ||
@@ -703,11 +707,12 @@ static unsigned int conf_ip4(unsigned int ifi,
  * @ifi:	Host interface to attempt (0 to determine one)
  * @ip6:	IPv6 context (will be written)
  * @mac:	MAC address to use (written if unset)
+ * @gwnat:	If set, use gateway as default nattohost address
  *
  * Return:	Interface index for IPv6, or 0 on failure.
  */
-static unsigned int conf_ip6(unsigned int ifi,
-			     struct ip6_ctx *ip6, unsigned char *mac)
+static unsigned int conf_ip6(unsigned int ifi, struct ip6_ctx *ip6,
+			     unsigned char *mac, bool gwnat)
 {
 	int prefix_len = 0;
 
@@ -732,7 +737,8 @@ static unsigned int conf_ip6(unsigned int ifi,
 	if (MAC_IS_ZERO(mac))
 		nl_link(0, ifi, mac, 0, 0);
 
-	ip6->nattohost = ip6->router;
+	if (gwnat && IN6_IS_ADDR_UNSPECIFIED(&ip6->nattohost))
+		ip6->nattohost = ip6->router;
 
 	if (IN6_IS_ADDR_UNSPECIFIED(&ip6->router) ||
 	    IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ||
@@ -1163,6 +1169,7 @@ static void conf_ugid(char *runas, uid_t *uid, gid_t *gid)
 void conf(struct ctx *c, int argc, char **argv)
 {
 	int netns_only = 0;
+	int no_map_gw = 0;
 	struct option options[] = {
 		{"debug",	no_argument,		NULL,		'd' },
 		{"quiet",	no_argument,		NULL,		'q' },
@@ -1191,7 +1198,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' },
@@ -1671,9 +1678,9 @@ void conf(struct ctx *c, int argc, char **argv)
 
 	nl_sock_init(c, false);
 	if (!v6_only)
-		c->ifi4 = conf_ip4(ifi4, &c->ip4, c->mac);
+		c->ifi4 = conf_ip4(ifi4, &c->ip4, c->mac, !no_map_gw);
 	if (!v4_only)
-		c->ifi6 = conf_ip6(ifi6, &c->ip6, c->mac);
+		c->ifi6 = conf_ip6(ifi6, &c->ip6, c->mac, !no_map_gw);
 	if ((!c->ifi4 && !c->ifi6) ||
 	    (*c->ip4.ifname_out && !c->ifi4) ||
 	    (*c->ip6.ifname_out && !c->ifi6))
diff --git a/passt.h b/passt.h
index e308fe1..9f05bca 100644
--- a/passt.h
+++ b/passt.h
@@ -201,7 +201,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
  */
@@ -261,7 +260,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/tcp.c b/tcp.c
index b0dacab..aa65d6e 100644
--- a/tcp.c
+++ b/tcp.c
@@ -2040,12 +2040,10 @@ static void tcp_conn_from_tap(struct ctx *c, int af, const void *addr,
 		if ((s = tcp_conn_new_sock(c, af)) < 0)
 			return;
 
-	if (!c->no_map_gw) {
-		if (af == AF_INET && IN4_ARE_ADDR_EQUAL(addr, &c->ip4.nattohost))
-			addr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-		if (af == AF_INET6 && IN6_ARE_ADDR_EQUAL(addr, &c->ip6.nattohost))
-			addr6.sin6_addr	= in6addr_loopback;
-	}
+	if (af == AF_INET && IN4_ARE_ADDR_EQUAL(addr, &c->ip4.nattohost))
+		addr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+	if (af == AF_INET6 && IN6_ARE_ADDR_EQUAL(addr, &c->ip6.nattohost))
+		addr6.sin6_addr	= in6addr_loopback;
 
 	if (af == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr)) {
 		struct sockaddr_in6 addr6_ll = {
diff --git a/udp.c b/udp.c
index 1533cee..6234a8d 100644
--- a/udp.c
+++ b/udp.c
@@ -841,8 +841,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr,
 		if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.dns_match) &&
 		    ntohs(s_in.sin_port) == 53) {
 			s_in.sin_addr = c->ip4.dns_host;
-		} else if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.nattohost) &&
-			   !c->no_map_gw) {
+		} else if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.nattohost)) {
 			if (!(udp_tap_map[V4][dst].flags & PORT_LOCAL) ||
 			    (udp_tap_map[V4][dst].flags & PORT_LOOPBACK))
 				s_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -887,8 +886,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr,
 		if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.dns_match) &&
 		    ntohs(s_in6.sin6_port) == 53) {
 			s_in6.sin6_addr = c->ip6.dns_host;
-		} else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.nattohost) &&
-			   !c->no_map_gw) {
+		} else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.nattohost)) {
 			if (!(udp_tap_map[V6][dst].flags & PORT_LOCAL) ||
 			    (udp_tap_map[V6][dst].flags & PORT_LOOPBACK))
 				s_in6.sin6_addr = in6addr_loopback;
-- 
@@ -841,8 +841,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr,
 		if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.dns_match) &&
 		    ntohs(s_in.sin_port) == 53) {
 			s_in.sin_addr = c->ip4.dns_host;
-		} else if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.nattohost) &&
-			   !c->no_map_gw) {
+		} else if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.nattohost)) {
 			if (!(udp_tap_map[V4][dst].flags & PORT_LOCAL) ||
 			    (udp_tap_map[V4][dst].flags & PORT_LOOPBACK))
 				s_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -887,8 +886,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr,
 		if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.dns_match) &&
 		    ntohs(s_in6.sin6_port) == 53) {
 			s_in6.sin6_addr = c->ip6.dns_host;
-		} else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.nattohost) &&
-			   !c->no_map_gw) {
+		} else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.nattohost)) {
 			if (!(udp_tap_map[V6][dst].flags & PORT_LOCAL) ||
 			    (udp_tap_map[V6][dst].flags & PORT_LOOPBACK))
 				s_in6.sin6_addr = in6addr_loopback;
-- 
2.40.1


  parent reply	other threads:[~2023-05-01 11:08 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-01 11:06 [PATCH 0/7] RFC: Allow NAT-to-host address to be configured explicitly David Gibson
2023-05-01 11:06 ` [PATCH 1/7] udp: Simplify setting of source IPv6 address for inbound packets David Gibson
2023-05-01 11:06 ` [PATCH 2/7] udp: Simplify setting od destination " David Gibson
2023-05-04 21:53   ` Stefano Brivio
2023-05-01 11:06 ` [PATCH 3/7] nat: Split notion of gateway/router from from guest-visible host address David Gibson
2023-05-01 11:06 ` David Gibson [this message]
2023-05-01 11:07 ` [PATCH 5/7] nat: Centralise handling of gateway versus link-local address for host NAT David Gibson
2023-05-01 11:07 ` [PATCH 6/7] Allow nat-to-host addresses to be overridden David Gibson
2023-05-01 11:07 ` [PATCH 7/7] nat, test: Test --nat-to-host option David Gibson
2023-05-02 21:52 ` [PATCH 0/7] RFC: Allow NAT-to-host address to be configured explicitly Stefano Brivio

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230501110702.3915529-5-david@gibson.dropbear.id.au \
    --to=david@gibson.dropbear.id.au \
    --cc=passt-dev@passt.top \
    --cc=sbrivio@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).