public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: Stefano Brivio <sbrivio@redhat.com>
To: passt-dev@passt.top
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH] conf, udp: Drop mostly duplicated dns_send arrays, rename related fields
Date: Thu, 10 Nov 2022 20:35:08 +0100	[thread overview]
Message-ID: <20221110193508.968090-1-sbrivio@redhat.com> (raw)

Given that we use just the first valid DNS resolver address
configured, or read from resolv.conf(5) on the host, to forward DNS
queries to, in case --dns-forward is used, we don't need to duplicate
dns[] to dns_send[]:

- rename dns_send[] back to dns[]: those are the resolvers we
  advertise to the guest/container

- for forwarding purposes, instead of dns[], use a single field (for
  each protocol version): dns_host

- and rename dns_fwd to dns_match, so that it's clear this is the
  address we are matching DNS queries against, to decide if they need
  to be forwarded

Suggested-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
 conf.c   | 76 ++++++++++++++++++++++++--------------------------------
 dhcp.c   |  5 ++--
 dhcpv6.c |  5 ++--
 ndp.c    |  6 ++---
 passt.h  | 20 +++++++--------
 udp.c    | 21 +++++++++-------
 6 files changed, 62 insertions(+), 71 deletions(-)

diff --git a/conf.c b/conf.c
index 1adcf83..a995eb7 100644
--- a/conf.c
+++ b/conf.c
@@ -355,11 +355,9 @@ overlap:
  */
 static void get_dns(struct ctx *c)
 {
-	struct in6_addr *dns6_send = &c->ip6.dns_send[0];
-	struct in_addr *dns4_send = &c->ip4.dns_send[0];
+	struct in6_addr *dns6 = &c->ip6.dns[0], dns6_tmp;
+	struct in_addr *dns4 = &c->ip4.dns[0], dns4_tmp;
 	int dns4_set, dns6_set, dnss_set, dns_set, fd;
-	struct in6_addr *dns6 = &c->ip6.dns[0];
-	struct in_addr *dns4 = &c->ip4.dns[0];
 	struct fqdn *s = c->dns_search;
 	struct lineread resolvconf;
 	int line_len;
@@ -388,49 +386,44 @@ static void get_dns(struct ctx *c)
 				*end = 0;
 
 			if (!dns4_set &&
-			    dns4 - &c->ip4.dns[0] < ARRAY_SIZE(c->ip4.dns) - 1 &&
-			    inet_pton(AF_INET, p + 1, dns4)) {
+			    dns4 - &c->ip4.dns[0] < ARRAY_SIZE(c->ip4.dns) - 1
+			    && inet_pton(AF_INET, p + 1, &dns4_tmp)) {
 				/* Guest or container can only access local
 				 * addresses via local redirect
 				 */
-				if (IN4_IS_ADDR_LOOPBACK(dns4)) {
+				if (IN4_IS_ADDR_LOOPBACK(&dns4_tmp)) {
 					if (!c->no_map_gw) {
-						*dns4_send = c->ip4.gw;
-						dns4_send++;
+						*dns4 = c->ip4.gw;
+						dns4++;
 					}
 				} else {
-					*dns4_send = *dns4;
-					dns4_send++;
+					*dns4 = dns4_tmp;
+					dns4++;
 				}
 
-				dns4++;
-
-				dns4->s_addr = htonl(INADDR_ANY);
-				dns4_send->s_addr = htonl(INADDR_ANY);
+				if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_host))
+					c->ip4.dns_host = dns4_tmp;
 			}
 
 			if (!dns6_set &&
-			    dns6 - &c->ip6.dns[0] < ARRAY_SIZE(c->ip6.dns) - 1 &&
-			    inet_pton(AF_INET6, p + 1, dns6)) {
+			    dns6 - &c->ip6.dns[0] < ARRAY_SIZE(c->ip6.dns) - 1
+			    && inet_pton(AF_INET6, p + 1, &dns6_tmp)) {
 				/* Guest or container can only access local
 				 * addresses via local redirect
 				 */
-				if (IN6_IS_ADDR_LOOPBACK(dns6)) {
+				if (IN6_IS_ADDR_LOOPBACK(&dns6_tmp)) {
 					if (!c->no_map_gw) {
-						memcpy(dns6_send, &c->ip6.gw,
-						       sizeof(*dns6_send));
-						dns6_send++;
+						memcpy(dns6, &c->ip6.gw,
+						       sizeof(*dns6));
+						dns6++;
 					}
 				} else {
-					memcpy(dns6_send, dns6,
-					       sizeof(*dns6_send));
-					dns6_send++;
+					memcpy(dns6, &dns6_tmp, sizeof(*dns6));
+					dns6++;
 				}
 
-				dns6++;
-
-				memset(dns6, 0, sizeof(*dns6));
-				memset(dns6_send, 0, sizeof(*dns6_send));
+				if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_host))
+					c->ip6.dns_host = dns6_tmp;
 			}
 		} else if (!dnss_set && strstr(line, "search ") == line &&
 			   s == c->dns_search) {
@@ -897,12 +890,10 @@ static void conf_print(const struct ctx *c)
 			     inet_ntop(AF_INET, &c->ip4.gw,   buf4, sizeof(buf4)));
 		}
 
-		for (i = 0; !IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_send[i]);
-		     i++) {
+		for (i = 0; !IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns[i]); i++) {
 			if (!i)
 				info("DNS:");
-			inet_ntop(AF_INET, &c->ip4.dns_send[i], buf4,
-				  sizeof(buf4));
+			inet_ntop(AF_INET, &c->ip4.dns[i], buf4, sizeof(buf4));
 			info("    %s", buf4);
 		}
 
@@ -933,8 +924,7 @@ static void conf_print(const struct ctx *c)
 		     inet_ntop(AF_INET6, &c->ip6.addr_ll, buf6, sizeof(buf6)));
 
 dns6:
-		for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_send[i]);
-		     i++) {
+		for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns[i]); i++) {
 			if (!i)
 				info("DNS:");
 			inet_ntop(AF_INET6, &c->ip6.dns[i], buf6, sizeof(buf6));
@@ -1230,17 +1220,17 @@ void conf(struct ctx *c, int argc, char **argv)
 			c->no_dhcp_dns_search = 1;
 			break;
 		case 9:
-			if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_fwd)	&&
-			    inet_pton(AF_INET6, optarg, &c->ip6.dns_fwd) &&
-			    !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_fwd)	&&
-			    !IN6_IS_ADDR_LOOPBACK(&c->ip6.dns_fwd))
+			if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match)     &&
+			    inet_pton(AF_INET6, optarg, &c->ip6.dns_match) &&
+			    !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match)    &&
+			    !IN6_IS_ADDR_LOOPBACK(&c->ip6.dns_match))
 				break;
 
-			if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_fwd)	&&
-			    inet_pton(AF_INET, optarg, &c->ip4.dns_fwd)	&&
-			    !IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_fwd)	&&
-			    !IN4_IS_ADDR_BROADCAST(&c->ip4.dns_fwd)	&&
-			    !IN4_IS_ADDR_LOOPBACK(&c->ip4.dns_fwd))
+			if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_match)    &&
+			    inet_pton(AF_INET, optarg, &c->ip4.dns_match) &&
+			    !IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_match)   &&
+			    !IN4_IS_ADDR_BROADCAST(&c->ip4.dns_match)     &&
+			    !IN4_IS_ADDR_LOOPBACK(&c->ip4.dns_match))
 				break;
 
 			err("Invalid DNS forwarding address: %s", optarg);
diff --git a/dhcp.c b/dhcp.c
index 12da47a..6088886 100644
--- a/dhcp.c
+++ b/dhcp.c
@@ -359,9 +359,8 @@ int dhcp(const struct ctx *c, const struct pool *p)
 	}
 
 	for (i = 0, opts[6].slen = 0;
-	     !c->no_dhcp_dns && !IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_send[i]);
-	     i++) {
-		((struct in_addr *)opts[6].s)[i] = c->ip4.dns_send[i];
+	     !c->no_dhcp_dns && !IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns[i]); i++) {
+		((struct in_addr *)opts[6].s)[i] = c->ip4.dns[i];
 		opts[6].slen += sizeof(uint32_t);
 	}
 
diff --git a/dhcpv6.c b/dhcpv6.c
index 67262e6..e763aed 100644
--- a/dhcpv6.c
+++ b/dhcpv6.c
@@ -379,7 +379,7 @@ static size_t dhcpv6_dns_fill(const struct ctx *c, char *buf, int offset)
 	if (c->no_dhcp_dns)
 		goto search;
 
-	for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_send[i]); i++) {
+	for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns[i]); i++) {
 		if (!i) {
 			srv = (struct opt_dns_servers *)(buf + offset);
 			offset += sizeof(struct opt_hdr);
@@ -387,8 +387,7 @@ static size_t dhcpv6_dns_fill(const struct ctx *c, char *buf, int offset)
 			srv->hdr.l = 0;
 		}
 
-		memcpy(&srv->addr[i], &c->ip6.dns_send[i],
-		       sizeof(srv->addr[i]));
+		memcpy(&srv->addr[i], &c->ip6.dns[i], sizeof(srv->addr[i]));
 		srv->hdr.l += sizeof(srv->addr[i]);
 		offset += sizeof(srv->addr[i]);
 	}
diff --git a/ndp.c b/ndp.c
index 6d79477..80e1f19 100644
--- a/ndp.c
+++ b/ndp.c
@@ -121,7 +121,7 @@ int ndp(struct ctx *c, const struct icmp6hdr *ih, const struct in6_addr *saddr)
 		if (c->no_dhcp_dns)
 			goto dns_done;
 
-		for (n = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_send[n]); n++);
+		for (n = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns[n]); n++);
 		if (n) {
 			*p++ = 25;				/* RDNSS */
 			*p++ = 1 + 2 * n;			/* length */
@@ -130,8 +130,8 @@ int ndp(struct ctx *c, const struct icmp6hdr *ih, const struct in6_addr *saddr)
 			p += 4;
 
 			for (i = 0; i < n; i++) {
-				memcpy(p, &c->ip6.dns_send[i], 16);
-				p += 16;			/* address */
+				memcpy(p, &c->ip6.dns[i], 16);	/* address */
+				p += 16;
 			}
 
 			for (n = 0; *c->dns_search[n].n; n++)
diff --git a/passt.h b/passt.h
index e93eea8..6649c0a 100644
--- a/passt.h
+++ b/passt.h
@@ -101,9 +101,9 @@ enum passt_modes {
  * @addr_seen:		Latest IPv4 address seen as source from tap
  * @prefixlen:		IPv4 prefix length (netmask)
  * @gw:			Default IPv4 gateway, network order
- * @dns:		Host IPv4 DNS addresses, zero-terminated, network order
- * @dns_send:		Offered IPv4 DNS, zero-terminated, network order
- * @dns_fwd:		Address forwarded (UDP) to first IPv4 DNS, network order
+ * @dns:		DNS addresses for DHCP, zero-terminated, network order
+ * @dns_match:		Forward DNS query if sent to this address, network order
+ * @dns_host:		Use this DNS on the host for forwarding, network order
  */
 struct ip4_ctx {
 	struct in_addr addr;
@@ -111,8 +111,8 @@ struct ip4_ctx {
 	int prefix_len;
 	struct in_addr gw;
 	struct in_addr dns[MAXNS + 1];
-	struct in_addr dns_send[MAXNS + 1];
-	struct in_addr dns_fwd;
+	struct in_addr dns_match;
+	struct in_addr dns_host;
 };
 
 /**
@@ -122,9 +122,9 @@ struct ip4_ctx {
  * @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
- * @dns:		Host IPv6 DNS addresses, zero-terminated
- * @dns_send:		Offered IPv6 DNS addresses, zero-terminated
- * @dns_fwd:		Address forwarded (UDP) to first IPv6 DNS, network order
+ * @dns:		DNS addresses for DHCPv6 and NDP, zero-terminated
+ * @dns_match:		Forward DNS query if sent to this address
+ * @dns_host:		Use this DNS on the host for forwarding
  */
 struct ip6_ctx {
 	struct in6_addr addr;
@@ -133,8 +133,8 @@ struct ip6_ctx {
 	struct in6_addr addr_ll_seen;
 	struct in6_addr gw;
 	struct in6_addr dns[MAXNS + 1];
-	struct in6_addr dns_send[MAXNS + 1];
-	struct in6_addr dns_fwd;
+	struct in6_addr dns_match;
+	struct in6_addr dns_host;
 };
 
 #include <netinet/if_ether.h>
diff --git a/udp.c b/udp.c
index ff7f993..0aa6308 100644
--- a/udp.c
+++ b/udp.c
@@ -678,10 +678,10 @@ static void udp_sock_fill_data_v4(const struct ctx *c, int n,
 
 	src_port = ntohs(b->s_in.sin_port);
 
-	if (!IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_fwd) &&
-	    IN4_ARE_ADDR_EQUAL(&b->s_in.sin_addr, &c->ip4.dns[0]) &&
+	if (!IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_match) &&
+	    IN4_ARE_ADDR_EQUAL(&b->s_in.sin_addr, &c->ip4.dns_host) &&
 	    src_port == 53) {
-		b->iph.saddr = c->ip4.dns_fwd.s_addr;
+		b->iph.saddr = c->ip4.dns_match.s_addr;
 	} else if (IN4_IS_ADDR_LOOPBACK(&b->s_in.sin_addr) ||
 		   IN4_IS_ADDR_UNSPECIFIED(&b->s_in.sin_addr)||
 		   IN4_ARE_ADDR_EQUAL(&b->s_in.sin_addr, &c->ip4.addr_seen)) {
@@ -770,10 +770,11 @@ static void udp_sock_fill_data_v6(const struct ctx *c, int n,
 	if (IN6_IS_ADDR_LINKLOCAL(src)) {
 		b->ip6h.daddr = c->ip6.addr_ll_seen;
 		b->ip6h.saddr = b->s_in6.sin6_addr;
-	} else if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_fwd) &&
-		   IN6_ARE_ADDR_EQUAL(src, &c->ip6.dns[0]) && src_port == 53) {
+	} else if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match) &&
+		   IN6_ARE_ADDR_EQUAL(src, &c->ip6.dns_host) &&
+		   src_port == 53) {
 		b->ip6h.daddr = c->ip6.addr_seen;
-		b->ip6h.saddr = c->ip6.dns_fwd;
+		b->ip6h.saddr = c->ip6.dns_match;
 	} else if (IN6_IS_ADDR_LOOPBACK(src)			||
 		   IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr_seen)	||
 		   IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr)) {
@@ -1016,13 +1017,15 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr,
 
 		udp_tap_map[V4][src].ts = now->tv_sec;
 
-		if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.gw) && !c->no_map_gw) {
+		if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.gw) &&
+		    !c->no_map_gw) {
 			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);
 			else
 				s_in.sin_addr = c->ip4.addr_seen;
-		} else if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.dns_fwd) &&
+		} else 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[0];
 		}
@@ -1045,7 +1048,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr,
 				s_in6.sin6_addr = c->ip6.addr;
 			else
 				s_in6.sin6_addr = c->ip6.addr_seen;
-		} else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.dns_fwd) &&
+		} else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.dns_match) &&
 			   ntohs(s_in6.sin6_port) == 53) {
 			s_in6.sin6_addr = c->ip6.dns[0];
 		} else if (IN6_IS_ADDR_LINKLOCAL(&s_in6.sin6_addr)) {
-- 
@@ -678,10 +678,10 @@ static void udp_sock_fill_data_v4(const struct ctx *c, int n,
 
 	src_port = ntohs(b->s_in.sin_port);
 
-	if (!IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_fwd) &&
-	    IN4_ARE_ADDR_EQUAL(&b->s_in.sin_addr, &c->ip4.dns[0]) &&
+	if (!IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_match) &&
+	    IN4_ARE_ADDR_EQUAL(&b->s_in.sin_addr, &c->ip4.dns_host) &&
 	    src_port == 53) {
-		b->iph.saddr = c->ip4.dns_fwd.s_addr;
+		b->iph.saddr = c->ip4.dns_match.s_addr;
 	} else if (IN4_IS_ADDR_LOOPBACK(&b->s_in.sin_addr) ||
 		   IN4_IS_ADDR_UNSPECIFIED(&b->s_in.sin_addr)||
 		   IN4_ARE_ADDR_EQUAL(&b->s_in.sin_addr, &c->ip4.addr_seen)) {
@@ -770,10 +770,11 @@ static void udp_sock_fill_data_v6(const struct ctx *c, int n,
 	if (IN6_IS_ADDR_LINKLOCAL(src)) {
 		b->ip6h.daddr = c->ip6.addr_ll_seen;
 		b->ip6h.saddr = b->s_in6.sin6_addr;
-	} else if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_fwd) &&
-		   IN6_ARE_ADDR_EQUAL(src, &c->ip6.dns[0]) && src_port == 53) {
+	} else if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match) &&
+		   IN6_ARE_ADDR_EQUAL(src, &c->ip6.dns_host) &&
+		   src_port == 53) {
 		b->ip6h.daddr = c->ip6.addr_seen;
-		b->ip6h.saddr = c->ip6.dns_fwd;
+		b->ip6h.saddr = c->ip6.dns_match;
 	} else if (IN6_IS_ADDR_LOOPBACK(src)			||
 		   IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr_seen)	||
 		   IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr)) {
@@ -1016,13 +1017,15 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr,
 
 		udp_tap_map[V4][src].ts = now->tv_sec;
 
-		if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.gw) && !c->no_map_gw) {
+		if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.gw) &&
+		    !c->no_map_gw) {
 			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);
 			else
 				s_in.sin_addr = c->ip4.addr_seen;
-		} else if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.dns_fwd) &&
+		} else 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[0];
 		}
@@ -1045,7 +1048,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr,
 				s_in6.sin6_addr = c->ip6.addr;
 			else
 				s_in6.sin6_addr = c->ip6.addr_seen;
-		} else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.dns_fwd) &&
+		} else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.dns_match) &&
 			   ntohs(s_in6.sin6_port) == 53) {
 			s_in6.sin6_addr = c->ip6.dns[0];
 		} else if (IN6_IS_ADDR_LINKLOCAL(&s_in6.sin6_addr)) {
-- 
2.35.1


             reply	other threads:[~2022-11-10 19:35 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-10 19:35 Stefano Brivio [this message]
2022-11-15  2:36 ` [PATCH] conf, udp: Drop mostly duplicated dns_send arrays, rename related fields 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=20221110193508.968090-1-sbrivio@redhat.com \
    --to=sbrivio@redhat.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=passt-dev@passt.top \
    /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).