From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202606 header.b=T7GEIM4P; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 77D105A0262 for ; Mon, 27 Jul 2026 03:53:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202606; t=1785117181; bh=K6etORBjqHatWNw75MzPX2YuAq7s+FQcZPXi8KfgtHg=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=T7GEIM4PqiQyXlun2D3Ki6CxZqIiBwfFNOpK5zwNIlxAH8QNQ0xkLYuuaJpEb70aG d76Yphvo2Xu2H0Z2vJXrWCNJ3y2VfHj9IN7aNfpYyBru73aLKHg2Cjp7uOtlmXeRI8 gfT3kbKtPdLCuhQ/s4KOblbgN+0Iev1yR17O7Ft073s/9rP061Rxqu1rAPcs8Lkx/x wH5XxluWAkG9DBXbLZR8bMI0Uinxq3JMDc4bVbl+R/3ODcutQ6gU+Hs0Ur0XBsrfEY Ssdodee7jF8DzBG9i07E3/RxncuvUQp5Qk+wX2VDQRbdeHcTKAefwP8rNcKa7+ScII zQnRoZXiSLKEA== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4h7hSY71v3z4w1p; Mon, 27 Jul 2026 11:53:01 +1000 (AEST) Date: Mon, 27 Jul 2026 11:52:50 +1000 From: David Gibson To: Stefano Brivio Subject: Re: [PATCH 2/2] conf, fwd: Prefer same-scope address as inbound source address from host Message-ID: References: <20260722232639.1105561-1-sbrivio@redhat.com> <20260722232639.1105561-3-sbrivio@redhat.com> <20260723114234.2266f6dc@elisabeth> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="hhdD/rO5IwCDnvPG" Content-Disposition: inline In-Reply-To: <20260723114234.2266f6dc@elisabeth> Message-ID-Hash: CHG7UFQ3J7HXSQGUCYYSYS657EX4TBFF X-Message-ID-Hash: CHG7UFQ3J7HXSQGUCYYSYS657EX4TBFF 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: passt-dev@passt.top, Jan =?iso-8859-1?Q?Rod=E1k?= , Paul Holzinger 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: --hhdD/rO5IwCDnvPG Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, Jul 23, 2026 at 11:42:36AM +0200, Stefano Brivio wrote: > On Thu, 23 Jul 2026 13:36:58 +1000 > David Gibson wrote: >=20 > > On Thu, Jul 23, 2026 at 01:26:39AM +0200, Stefano Brivio wrote: > > > We might have situations, such as the one described in > > > https://bugs.passt.top/show_bug.cgi?id=3D217, where using a link-local > > > address as source in a given namespace doesn't guarantee that we can > > > reach the intended destination, because, for instance, the inbound > > > traffic we forward is in turn forwarded to a different interface, such > > > as a bridge. > > >=20 > > > In that case, the assumption from 9618d247006a ("ndp, dhcpv6, tcp, > > > udp: Always use link-local as source if gateway isn't") isn't a safe > > > one: the user might have specified a valid gateway address, matching > > > the scope of the destination address, but we won't use it as address > > > of last resort, and prefer a link-local address with a mismatch in > > > scope instead. > > >=20 > > > This should only be an issue in IPv6 local mode, because, otherwise, > > > we source address and default gateway address (presumably compatible) > > > from the host. > > >=20 > > > So, in local mode, if the user specifies a given default gateway > > > address for IPv6, note that as 'our_tap_addr', like we would do with > > > with IPv4, and stick to Rule 2 of RFC 6724, Section 5, when selecting > > > a source address, by preferring an address with the same scope, if > > > available. > > >=20 > > > Reported-by: Paul Holzinger > > > Link: https://bugs.passt.top/show_bug.cgi?id=3D217 > > > Signed-off-by: Stefano Brivio =20 > >=20 > > Reviewed-by: David Gibson > >=20 > > [snip] > > > diff --git a/fwd.c b/fwd.c > > > index 7152169..4ba0af3 100644 > > > --- a/fwd.c > > > +++ b/fwd.c > > > @@ -1090,7 +1090,11 @@ uint8_t fwd_nat_from_host(const struct ctx *c, > > > return PIF_NONE; > > > tgt->oaddr =3D inany_from_v4(c->ip4.our_tap_addr); > > > } else { > > > - tgt->oaddr.a6 =3D c->ip6.our_tap_ll; > > > + if (inany_is_linklocal6(&tgt->eaddr) || =20 > >=20 > > Just to make sure you're aware: this will only trigger if tgt->eaddr > > has been set at this point, which is not always the case. In fact it > > will usually only be the case when the rule specifies a target > > address. In other cases we pick tgt->oaddr first then pick > > tgt->eaddr's scope to try to match it. >=20 > Right, yes, I had half a mind to try and change this slightly (see > below) but then I realised that luckily it wasn't needed for this > minimal fix, as Podman will specify an explicit destination address, so > I preferred to avoid the topic altogether for the moment (including > avoiding comments that risk ignoring some corner cases) because: >=20 > > I think the fact that the order in which we pick eaddr and oaddr > > varies is pretty confusing, but I haven't so far seen a way to avoid > > it without breaking something worse. >=20 > ...I think that, at least in the !nat_inbound() case, we should avoid > a strict ordering in the selection of source and destination address > (we should look into both at the same time) because in general we know > upfront if we can match the scope between source and destination, I'm not entirely sure what you mean by that. > and we > should always try to do that (same here, RFC 6724 Section 5 Rule 2). AFAICT the RFC rules are assuming you already know the destination address. > And, if there are multiple ways to match the scopes, we should prefer > the most specific / smaller common scope (same rule as above, Section > 3.1 helps in the interpretation). Ok, makes sense, although again I'm not sure it really follows from the RFC which seems to assume a known destination. > But this would be much simpler to implement once we have Jon's changes > generalising address storage, because at that point we could have a > lookup function for the smallest scope of usable address, or even a > joint lookup function altogether. In detail, I think we should do this > (again, under the !nat_inbound() condition): Right. >=20 > 1. if there's a possible link-local source address and a possible > destination source address, pick both Did you mean specifically a link-local possible destination address here? > 2. if there's a possible unicast source address and a possible unicast > destination address, pick both >=20 > 3. if there's a possible link-local source address, pick it, and then > pick any (mismatching) destination address >=20 > 4. otherwise, pick any available source address, and any available > destination address >=20 > ...and once we have that series, we can probably avoid implementing > these as distinct steps. I would defer all this to that point, and > meanwhile just fix whatever critical case might come up (like the > current one with Podman). Ok. > > I still think this change is correct: not previously having > > ip6.our_tap_addr was only possible because we did this odd dance to > > pick eaddr based on oaddr's scope rather than the other way around. > >=20 > > > + IN6_IS_ADDR_UNSPECIFIED(&c->ip6.our_tap_addr)) > > > + tgt->oaddr.a6 =3D c->ip6.our_tap_ll; > > > + else > > > + tgt->oaddr.a6 =3D c->ip6.our_tap_addr; > > > } > > > } > > > tgt->oport =3D ini->eport; > > > diff --git a/passt.h b/passt.h > > > index a61baca..51ccd4f 100644 > > > --- a/passt.h > > > +++ b/passt.h > > > @@ -121,6 +121,7 @@ struct ip4_ctx { > > > * @dns: DNS addresses for DHCPv6 and NDP > > > * @dns_match: Forward DNS query if sent to this address > > > * @our_tap_ll: Link-local IPv6 address for passt's use on tap > > > + * @our_tap_addr: Non-LL IPv6 address for passt's use on tap (if any) > > > * @dns_host: Use this DNS on the host for forwarding > > > * @addr_out: Optional source address for outbound traffic > > > * @ifname_out: Optional interface name to bind outbound sockets to > > > @@ -140,6 +141,7 @@ struct ip6_ctx { > > > struct in6_addr dns[MAXNS]; > > > struct in6_addr dns_match; > > > struct in6_addr our_tap_ll; > > > + struct in6_addr our_tap_addr; > > > =20 > > > /* PIF_HOST addresses */ > > > struct in6_addr dns_host; > > > --=20 > > > 2.43.0 >=20 > --=20 > Stefano >=20 --=20 David Gibson (he or they) | 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 --hhdD/rO5IwCDnvPG Content-Type: application/pgp-signature; name=signature.asc -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmpmueYACgkQzQJF27ox 2Genbg/6A3rbSOqCv2T494PCkFUN2+OGYUrPcbqRVAVBaUxHyG7ua6Nyj3VJoiKb G1E4tliIRPGIbl1V9x6tXt/vSBaiOOZOAXWwPYhZRfEtPbjl3wWoEPjFqgz8CKNX z11FdaMFB6gDEBzPLQ4grEc3vqbn0fHy4SuObH2Jy2p+JThqYMnWYJaN7RrDgWCc 41PQvh/53WkMa1k33nMj1RE4PATYY41v2MCSd4fC31GJ7eo1zksbSXPqmkcwcDB5 qVNzGEy7N3MTvHXq84Ytf/j07fSGY0Cun/xR2RLSCCys19XsbuVzSUkIT+i5xVlb zuGB67Y1+YAUOUv0QbqAGkRzmxUe1ua39L2qyN33jtaQqOlSvhjWLML068yOqBl9 dLvAY9AXKHlsIws4ShIXXBSsRsl6RIWMRABR3x6+Iuey694I/0/sVduhUT+ALxHx 5vtkIaR1Yv80xLqn38IecSCfsVjhmGzz1t9QrM1cbOEXdfFKLZRTX2DHJqBHLnuM xeKaYjDizr4RFpiR9msWz07uBsF/BI86g+fx7KzhlA5MHqT6l9FyU5cYyJtIji4w EjlHkKZ06PBl37RbzQqMxfb5FtzzL8ep+xqtAukjnYfB4bR9A9UEyNYn5V+1/iTm O3wm4hC+ejn/1bCPIjr+byJ2mfryrM66xRvOaVt6s9jZaLr2qjM= =V52X -----END PGP SIGNATURE----- --hhdD/rO5IwCDnvPG--