From mboxrd@z Thu Jan 1 00:00:00 1970 Received: by passt.top (Postfix, from userid 1000) id 818655A026C; Thu, 3 Nov 2022 00:04:43 +0100 (CET) From: Stefano Brivio To: passt-dev@passt.top Subject: [PATCH 3/3] udp: Check for answers to forwarded DNS queries before handling local redirects Date: Thu, 3 Nov 2022 00:04:43 +0100 Message-Id: <20221102230443.377446-4-sbrivio@redhat.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221102230443.377446-1-sbrivio@redhat.com> References: <20221102230443.377446-1-sbrivio@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: EYCKQYOH6F3MVWVHSNT7AOKYGXWGPSH3 X-Message-ID-Hash: EYCKQYOH6F3MVWVHSNT7AOKYGXWGPSH3 X-MailFrom: sbrivio@passt.top X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Paul Holzinger , David Gibson X-Mailman-Version: 3.3.3 Precedence: list List-Id: Development discussion and patches for passt Archived-At: <> Archived-At: List-Archive: <> List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Now that we allow loopback DNS addresses to be used as targets for forwarding, we need to check if DNS answers come from those targets, before deciding to eventually remap traffic for local redirects. Otherwise, the source address won't match the one configured as forwarder, which means that the guest or the container will refuse those responses. Signed-off-by: Stefano Brivio --- udp.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/udp.c b/udp.c index 4b201d3..7c77e09 100644 --- a/udp.c +++ b/udp.c @@ -680,8 +680,10 @@ static void udp_sock_fill_data_v4(const struct ctx *c, int n, src = ntohl(b->s_in.sin_addr.s_addr); src_port = ntohs(b->s_in.sin_port); - if (src >> IN_CLASSA_NSHIFT == IN_LOOPBACKNET || - src == INADDR_ANY || src == ntohl(c->ip4.addr_seen)) { + if (c->ip4.dns_fwd && src == htonl(c->ip4.dns[0]) && src_port == 53) { + b->iph.saddr = c->ip4.dns_fwd; + } else if (IPV4_IS_LOOPBACK(src) || src == INADDR_ANY || + src == ntohl(c->ip4.addr_seen)) { b->iph.saddr = c->ip4.gw; udp_tap_map[V4][src_port].ts = now->tv_sec; udp_tap_map[V4][src_port].flags |= PORT_LOCAL; @@ -692,9 +694,6 @@ static void udp_sock_fill_data_v4(const struct ctx *c, int n, udp_tap_map[V4][src_port].flags |= PORT_LOOPBACK; bitmap_set(udp_act[V4][UDP_ACT_TAP], src_port); - } else if (c->ip4.dns_fwd && - src == htonl(c->ip4.dns[0]) && src_port == 53) { - b->iph.saddr = c->ip4.dns_fwd; } else { b->iph.saddr = b->s_in.sin_addr.s_addr; } @@ -770,6 +769,10 @@ 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) { + b->ip6h.daddr = c->ip6.addr_seen; + b->ip6h.saddr = c->ip6.dns_fwd; } else if (IN6_IS_ADDR_LOOPBACK(src) || IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr_seen) || IN6_ARE_ADDR_EQUAL(src, &c->ip6.addr)) { @@ -794,10 +797,6 @@ static void udp_sock_fill_data_v6(const struct ctx *c, int n, udp_tap_map[V6][src_port].flags &= ~PORT_GUA; bitmap_set(udp_act[V6][UDP_ACT_TAP], src_port); - } else if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_fwd) && - IN6_ARE_ADDR_EQUAL(src, &c->ip6.dns[0]) && src_port == 53) { - b->ip6h.daddr = c->ip6.addr_seen; - b->ip6h.saddr = c->ip6.dns_fwd; } else { b->ip6h.daddr = c->ip6.addr_seen; b->ip6h.saddr = b->s_in6.sin6_addr; -- 2.35.1