From: Stefano Brivio <sbrivio@redhat.com>
To: David Gibson <david@gibson.dropbear.id.au>
Cc: passt-dev@passt.top
Subject: Re: [PATCH 2/7] udp: Simplify setting od destination IPv6 address for inbound packets
Date: Thu, 4 May 2023 23:53:08 +0200 [thread overview]
Message-ID: <20230504235308.76f2b260@elisabeth> (raw)
In-Reply-To: <20230501110702.3915529-3-david@gibson.dropbear.id.au>
On Mon, 1 May 2023 21:06:57 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:
> 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 <david@gibson.dropbear.id.au>
> ---
> 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;
> -
This part...
> 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;
is not equivalent to this, and I guess not by intention.
The rationale for setting a link-local destination address if the
source address (on the host) is the loopback address (commit
86b273150a47 "tcp, udp: Allow binding ports in init namespace to
both tap and loopback"... not a great description) is that we might
otherwise collide with a global unicast destination address also
assigned to the host.
A link-local destination should be the only safe option. After all,
that's what link-local addresses are for: surely a packet with that
source address is local to the "link" to the guest.
If the source address matches the configured or observed address
(presumably local), the same reasoning applies: we want to actually
send that packet to the guest, and signal that it's local.
I guess this change might explain the failures you see: if we
already saw a non-link-local address from the guest, we'll use that
as destination, and the packet won't reach the guest.
The rest looks correct to me, and also the rest of the series...
just, as you mentioned, if we want to generalise this right away (and I
think it's a better approach), patches from 3/7 on will be
substantially different.
--
Stefano
next prev parent reply other threads:[~2023-05-04 21:53 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-01 11:06 [PATCH 0/7] RFC: Allow NAT-to-host address to be configured explicitly David Gibson
2023-05-01 11:06 ` [PATCH 1/7] udp: Simplify setting of source IPv6 address for inbound packets David Gibson
2023-05-01 11:06 ` [PATCH 2/7] udp: Simplify setting od destination " David Gibson
2023-05-04 21:53 ` Stefano Brivio [this message]
2023-05-01 11:06 ` [PATCH 3/7] nat: Split notion of gateway/router from from guest-visible host address David Gibson
2023-05-01 11:06 ` [PATCH 4/7] nat: Simplify --no-map-gw handling David Gibson
2023-05-01 11:07 ` [PATCH 5/7] nat: Centralise handling of gateway versus link-local address for host NAT David Gibson
2023-05-01 11:07 ` [PATCH 6/7] Allow nat-to-host addresses to be overridden David Gibson
2023-05-01 11:07 ` [PATCH 7/7] nat, test: Test --nat-to-host option David Gibson
2023-05-02 21:52 ` [PATCH 0/7] RFC: Allow NAT-to-host address to be configured explicitly Stefano Brivio
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=20230504235308.76f2b260@elisabeth \
--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).