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>
Cc: passt-dev@passt.top
Subject: Re: [PATCH] conf, udp: Drop mostly duplicated dns_send arrays, rename related fields
Date: Tue, 15 Nov 2022 13:36:23 +1100	[thread overview]
Message-ID: <Y3L7J74JKV0MAR5l@yekko> (raw)
In-Reply-To: <20221110193508.968090-1-sbrivio@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 13408 bytes --]

On Thu, Nov 10, 2022 at 08:35:08PM +0100, Stefano Brivio wrote:
> 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>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  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)) {

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

      reply	other threads:[~2022-11-15  4:38 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-10 19:35 [PATCH] conf, udp: Drop mostly duplicated dns_send arrays, rename related fields Stefano Brivio
2022-11-15  2:36 ` David Gibson [this message]

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=Y3L7J74JKV0MAR5l@yekko \
    --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).