From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gandalf.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 0726E5A026D for ; Mon, 1 May 2023 13:08:08 +0200 (CEST) Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4Q90n05Jy5z4x47; Mon, 1 May 2023 21:08:04 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=201602; t=1682939284; bh=uC5xdHfxbOrM7Zg7rYN1/RrZunv8ENAqB5eWbH1Z8oA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cE8PVf+LMNUwFVqRhMqNs/gy6k0UA/QF/sUMWyCU3GDvd5NdWUE/fHOzmH8tVubyN OhRy2tTb3HHoD057jtAKCfFf5fWay1FwAyWw806yqlc06R57f8AaH8rV7/75TGTOv5 9Coz+KOugFdExJ5RkDo8j6u2/UQf6Ow69RcqgMig= From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH 2/7] udp: Simplify setting od destination IPv6 address for inbound packets Date: Mon, 1 May 2023 21:06:57 +1000 Message-Id: <20230501110702.3915529-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230501110702.3915529-1-david@gibson.dropbear.id.au> References: <20230501110702.3915529-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: 35VV6GPGSFACXTDKU2ZOAMRFY4YO66GK X-Message-ID-Hash: 35VV6GPGSFACXTDKU2ZOAMRFY4YO66GK X-MailFrom: dgibson@gandalf.ozlabs.org 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: David Gibson X-Mailman-Version: 3.3.8 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: Depending on several possible NAT situations, udp_update_hdr6() has a few different paths for setting the destination IPv6 address. However, this isn't really separate from the selection of the IPv6 source address: if the adjusted source address is link-local then we need to use a link local destination, otherwise we need the global destination address. This fixes a small bug: it's theoretically possible, although unlikely, for the dns_match address to be link-local, in which case the previous code would have used the wrong destination. This does do slightly more work in the case of NATting packets originating on the host. Currently we always NAT those to a link-local address so we could statically set a link-local destination address, but we now recheck. However, as well as being simpler, the new approach is more robust if we want to allow non-link-local NAT-to-host addresses, which we do plan to in future. Signed-off-by: David Gibson --- udp.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/udp.c b/udp.c index 361f24c..9c96c0f 100644 --- a/udp.c +++ b/udp.c @@ -640,18 +640,13 @@ static size_t udp_update_hdr6(const struct ctx *c, int n, in_port_t dstport, b->ip6h.payload_len = htons(udp6_l2_mh_sock[n].msg_len + sizeof(b->uh)); - if (IN6_IS_ADDR_LINKLOCAL(src)) { - b->ip6h.daddr = c->ip6.addr_ll_seen; - } else if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match) && + 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; src = &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)) { - b->ip6h.daddr = c->ip6.addr_ll_seen; - udp_tap_map[V6][src_port].ts = now->tv_sec; udp_tap_map[V6][src_port].flags |= PORT_LOCAL; @@ -671,11 +666,13 @@ static size_t udp_update_hdr6(const struct ctx *c, int n, in_port_t dstport, src = &c->ip6.gw; else src = &c->ip6.addr_ll; - } else { - b->ip6h.daddr = c->ip6.addr_seen; } b->ip6h.saddr = *src; + if (IN6_IS_ADDR_LINKLOCAL(src)) + b->ip6h.daddr = c->ip6.addr_ll_seen; + else + b->ip6h.daddr = c->ip6.addr_seen; b->uh.source = b->s_in6.sin6_port; b->uh.dest = htons(dstport); -- 2.40.1