public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: passt-dev@passt.top, Stefano Brivio <sbrivio@redhat.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH 2/3] conf: Delay handling -D option until after addresses are configured
Date: Mon, 12 Aug 2024 19:53:54 +1000	[thread overview]
Message-ID: <20240812095355.1721876-3-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20240812095355.1721876-1-david@gibson.dropbear.id.au>

add_dns[46]() rely on the gateway address and c->no_map_gw being already
initialised, in order to properly handle DNS servers which need NAT to be
accessed from the guest.

Usually these are called from get_dns() which is well after the addresses
are configured, so that's fine.  However, they can also be called earlier
if an explicit -D command line option is given.  In this case no_map_gw
and/or c->ip[46].gw may not get be initialised properly, leading to this
doing the wrong thing.

Luckily we already have a second pass of option parsing for things which
need addresses to already be configured.  Move handling of -D to there.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 conf.c | 84 +++++++++++++++++++++++++++++++---------------------------
 1 file changed, 45 insertions(+), 39 deletions(-)

diff --git a/conf.c b/conf.c
index a79e7a66..76d37da0 100644
--- a/conf.c
+++ b/conf.c
@@ -1235,10 +1235,10 @@ void conf(struct ctx *c, int argc, char **argv)
 	const char *logname = (c->mode == MODE_PASTA) ? "pasta" : "passt";
 	char userns[PATH_MAX] = { 0 }, netns[PATH_MAX] = { 0 };
 	bool copy_addrs_opt = false, copy_routes_opt = false;
-	struct in6_addr *dns6 = c->ip6.dns, dns6_tmp;
-	struct in_addr *dns4 = c->ip4.dns, dns4_tmp;
 	enum fwd_ports_mode fwd_default = FWD_NONE;
 	bool v4_only = false, v6_only = false;
+	struct in6_addr *dns6 = c->ip6.dns;
+	struct in_addr *dns4 = c->ip4.dns;
 	struct fqdn *dnss = c->dns_search;
 	unsigned int ifi4 = 0, ifi6 = 0;
 	const char *logfile = NULL;
@@ -1545,40 +1545,6 @@ void conf(struct ctx *c, int argc, char **argv)
 			die("Invalid or redundant outbound address: %s",
 			    optarg);
 			break;
-		case 'D':
-			if (!strcmp(optarg, "none")) {
-				c->no_dns = 1;
-
-				dns4 = &c->ip4.dns[0];
-				memset(c->ip4.dns, 0, sizeof(c->ip4.dns));
-				c->ip4.dns[0]    = (struct in_addr){ 0 };
-				c->ip4.dns_match = (struct in_addr){ 0 };
-				c->ip4.dns_host  = (struct in_addr){ 0 };
-
-				dns6 = &c->ip6.dns[0];
-				memset(c->ip6.dns, 0, sizeof(c->ip6.dns));
-				c->ip6.dns_match = (struct in6_addr){ 0 };
-				c->ip6.dns_host  = (struct in6_addr){ 0 };
-
-				break;
-			}
-
-			c->no_dns = 0;
-
-			if (dns4 - &c->ip4.dns[0] < ARRAY_SIZE(c->ip4.dns) &&
-			    inet_pton(AF_INET, optarg, &dns4_tmp)) {
-				add_dns4(c, &dns4_tmp, &dns4);
-				break;
-			}
-
-			if (dns6 - &c->ip6.dns[0] < ARRAY_SIZE(c->ip6.dns) &&
-			    inet_pton(AF_INET6, optarg, &dns6_tmp)) {
-				add_dns6(c, &dns6_tmp, &dns6);
-				break;
-			}
-
-			die("Cannot use DNS address %s", optarg);
-			break;
 		case 'S':
 			if (!strcmp(optarg, "none")) {
 				c->no_dns_search = 1;
@@ -1620,6 +1586,7 @@ void conf(struct ctx *c, int argc, char **argv)
 		case 'u':
 		case 'T':
 		case 'U':
+		case 'D':
 			/* Handle these later, once addresses are configured */
 			break;
 		case 'h':
@@ -1677,16 +1644,55 @@ void conf(struct ctx *c, int argc, char **argv)
 	if (c->ifi6 && IN6_IS_ADDR_UNSPECIFIED(&c->ip6.gw))
 		c->no_map_gw = 1;
 
-	/* Inbound port options can be parsed now (after IPv4/IPv6 settings) */
+	/* Inbound port options & DNS can be parsed now (after IPv4/IPv6
+	 * settings)
+	 */
 	udp_portmap_clear();
 	optind = 1;
 	do {
 		name = getopt_long(argc, argv, optstring, options, NULL);
 
-		if (name == 't')
+		if (name == 't') {
 			conf_ports(c, name, optarg, &c->tcp.fwd_in);
-		else if (name == 'u')
+		} else if (name == 'u') {
 			conf_ports(c, name, optarg, &c->udp.fwd_in);
+		} else if (name == 'D') {
+			struct in6_addr dns6_tmp;
+			struct in_addr dns4_tmp;
+
+			if (!strcmp(optarg, "none")) {
+				c->no_dns = 1;
+
+				dns4 = &c->ip4.dns[0];
+				memset(c->ip4.dns, 0, sizeof(c->ip4.dns));
+				c->ip4.dns[0]    = (struct in_addr){ 0 };
+				c->ip4.dns_match = (struct in_addr){ 0 };
+				c->ip4.dns_host  = (struct in_addr){ 0 };
+
+				dns6 = &c->ip6.dns[0];
+				memset(c->ip6.dns, 0, sizeof(c->ip6.dns));
+				c->ip6.dns_match = (struct in6_addr){ 0 };
+				c->ip6.dns_host  = (struct in6_addr){ 0 };
+
+				continue;
+			}
+
+			c->no_dns = 0;
+
+			if (dns4 - &c->ip4.dns[0] < ARRAY_SIZE(c->ip4.dns) &&
+			    inet_pton(AF_INET, optarg, &dns4_tmp)) {
+				add_dns4(c, &dns4_tmp, &dns4);
+				break;
+			}
+
+			if (dns6 - &c->ip6.dns[0] < ARRAY_SIZE(c->ip6.dns) &&
+			    inet_pton(AF_INET6, optarg, &dns6_tmp)) {
+				add_dns6(c, &dns6_tmp, &dns6);
+				break;
+			}
+
+			die("Cannot use DNS address %s", optarg);
+		}
 	} while (name != -1);
 
 	if (c->mode == MODE_PASTA)
-- 
@@ -1235,10 +1235,10 @@ void conf(struct ctx *c, int argc, char **argv)
 	const char *logname = (c->mode == MODE_PASTA) ? "pasta" : "passt";
 	char userns[PATH_MAX] = { 0 }, netns[PATH_MAX] = { 0 };
 	bool copy_addrs_opt = false, copy_routes_opt = false;
-	struct in6_addr *dns6 = c->ip6.dns, dns6_tmp;
-	struct in_addr *dns4 = c->ip4.dns, dns4_tmp;
 	enum fwd_ports_mode fwd_default = FWD_NONE;
 	bool v4_only = false, v6_only = false;
+	struct in6_addr *dns6 = c->ip6.dns;
+	struct in_addr *dns4 = c->ip4.dns;
 	struct fqdn *dnss = c->dns_search;
 	unsigned int ifi4 = 0, ifi6 = 0;
 	const char *logfile = NULL;
@@ -1545,40 +1545,6 @@ void conf(struct ctx *c, int argc, char **argv)
 			die("Invalid or redundant outbound address: %s",
 			    optarg);
 			break;
-		case 'D':
-			if (!strcmp(optarg, "none")) {
-				c->no_dns = 1;
-
-				dns4 = &c->ip4.dns[0];
-				memset(c->ip4.dns, 0, sizeof(c->ip4.dns));
-				c->ip4.dns[0]    = (struct in_addr){ 0 };
-				c->ip4.dns_match = (struct in_addr){ 0 };
-				c->ip4.dns_host  = (struct in_addr){ 0 };
-
-				dns6 = &c->ip6.dns[0];
-				memset(c->ip6.dns, 0, sizeof(c->ip6.dns));
-				c->ip6.dns_match = (struct in6_addr){ 0 };
-				c->ip6.dns_host  = (struct in6_addr){ 0 };
-
-				break;
-			}
-
-			c->no_dns = 0;
-
-			if (dns4 - &c->ip4.dns[0] < ARRAY_SIZE(c->ip4.dns) &&
-			    inet_pton(AF_INET, optarg, &dns4_tmp)) {
-				add_dns4(c, &dns4_tmp, &dns4);
-				break;
-			}
-
-			if (dns6 - &c->ip6.dns[0] < ARRAY_SIZE(c->ip6.dns) &&
-			    inet_pton(AF_INET6, optarg, &dns6_tmp)) {
-				add_dns6(c, &dns6_tmp, &dns6);
-				break;
-			}
-
-			die("Cannot use DNS address %s", optarg);
-			break;
 		case 'S':
 			if (!strcmp(optarg, "none")) {
 				c->no_dns_search = 1;
@@ -1620,6 +1586,7 @@ void conf(struct ctx *c, int argc, char **argv)
 		case 'u':
 		case 'T':
 		case 'U':
+		case 'D':
 			/* Handle these later, once addresses are configured */
 			break;
 		case 'h':
@@ -1677,16 +1644,55 @@ void conf(struct ctx *c, int argc, char **argv)
 	if (c->ifi6 && IN6_IS_ADDR_UNSPECIFIED(&c->ip6.gw))
 		c->no_map_gw = 1;
 
-	/* Inbound port options can be parsed now (after IPv4/IPv6 settings) */
+	/* Inbound port options & DNS can be parsed now (after IPv4/IPv6
+	 * settings)
+	 */
 	udp_portmap_clear();
 	optind = 1;
 	do {
 		name = getopt_long(argc, argv, optstring, options, NULL);
 
-		if (name == 't')
+		if (name == 't') {
 			conf_ports(c, name, optarg, &c->tcp.fwd_in);
-		else if (name == 'u')
+		} else if (name == 'u') {
 			conf_ports(c, name, optarg, &c->udp.fwd_in);
+		} else if (name == 'D') {
+			struct in6_addr dns6_tmp;
+			struct in_addr dns4_tmp;
+
+			if (!strcmp(optarg, "none")) {
+				c->no_dns = 1;
+
+				dns4 = &c->ip4.dns[0];
+				memset(c->ip4.dns, 0, sizeof(c->ip4.dns));
+				c->ip4.dns[0]    = (struct in_addr){ 0 };
+				c->ip4.dns_match = (struct in_addr){ 0 };
+				c->ip4.dns_host  = (struct in_addr){ 0 };
+
+				dns6 = &c->ip6.dns[0];
+				memset(c->ip6.dns, 0, sizeof(c->ip6.dns));
+				c->ip6.dns_match = (struct in6_addr){ 0 };
+				c->ip6.dns_host  = (struct in6_addr){ 0 };
+
+				continue;
+			}
+
+			c->no_dns = 0;
+
+			if (dns4 - &c->ip4.dns[0] < ARRAY_SIZE(c->ip4.dns) &&
+			    inet_pton(AF_INET, optarg, &dns4_tmp)) {
+				add_dns4(c, &dns4_tmp, &dns4);
+				break;
+			}
+
+			if (dns6 - &c->ip6.dns[0] < ARRAY_SIZE(c->ip6.dns) &&
+			    inet_pton(AF_INET6, optarg, &dns6_tmp)) {
+				add_dns6(c, &dns6_tmp, &dns6);
+				break;
+			}
+
+			die("Cannot use DNS address %s", optarg);
+		}
 	} while (name != -1);
 
 	if (c->mode == MODE_PASTA)
-- 
2.46.0


  parent reply	other threads:[~2024-08-12  9:54 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-12  9:53 [PATCH 0/3] Assorted fixes related to addressing David Gibson
2024-08-12  9:53 ` [PATCH 1/3] Correct inaccurate comments on ip[46]_ctx::addr David Gibson
2024-08-12  9:53 ` David Gibson [this message]
2024-08-12  9:53 ` [PATCH 3/3] fwd: Rework inconsistencies in translation of inbound flows David Gibson
2024-08-12 21:51   ` Stefano Brivio
2024-08-15  5:01     ` David Gibson

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=20240812095355.1721876-3-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).