From: David Gibson <david@gibson.dropbear.id.au>
To: Stefano Brivio <sbrivio@redhat.com>
Cc: passt-dev@passt.top
Subject: Re: [PATCH 1/3] fwd_rule: Parse target adddresses for forwarding rules
Date: Thu, 2 Jul 2026 16:08:48 +1000 [thread overview]
Message-ID: <akYAcEF3l5xdPiHS@zatzit> (raw)
In-Reply-To: <20260702073109.35613343@elisabeth>
[-- Attachment #1: Type: text/plain, Size: 5831 bytes --]
On Thu, Jul 02, 2026 at 07:31:10AM +0200, Stefano Brivio wrote:
> On Thu, 2 Jul 2026 15:21:29 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
>
> > On Thu, Jul 02, 2026 at 06:58:23AM +0200, Stefano Brivio wrote:
[snip]
> > > > @@ -481,6 +495,12 @@ static bool parse_port_chunk(const char **cursor,
> > > > kind = CHUNK_INCLUDE;
> > > >
> > > > if (parse_literal(&p, ":")) {
> > > > + const char *tgtspec = p;
> > > > +
> > > > + if (!parse_inany(&p, &taddr_tmp) ||
> > > > + !parse_literal(&p, "/"))
> > >
> > > This is to support ":/PORT" together with ":ADDR/PORT", right?
> >
> > No, this is checking for the case where we didn't get a target address
> > at all. De Morgan's law might make it clearer:
> > !(<parsed IP> && <parsed "/")
>
> Right, yes, I understand, but you're doing the check this way because
> "/PORT" without address would be accepted, right?
No, I'm not, and it won't - in fact it's almost exactly the opposite.
If parse_inany() fails (which it will on an empty "address"), we won't
even call parse_literal() because of the rules of ||
> Otherwise checking
> for !parse_inany(&p, &taddr_tmp) would have been enough?
Not really, this is here so that we *don't* do anything with an
address that *isn't* followed by a /. Instead we backtrack and try
parse as something else instead. In fact that will (I'm pretty sure,
necessarily) also fail, but that's looking at parts of the grammar
outside what this specific piece is dealing with.
The idea here is that we consume either "ADDR/" or we consume nothing
at all before going on to parse the port range.
> Anyway, not so important, if the next version looks different anyway.
Right, though whether it's any less confusing is another question :/.
Like I said, I'm not thrilled with how this parsing stuff turned out,
but I spent two weeks and couldn't come up with something that wasn't
at least as bad in one way or another.
> > But I already reworked this to allow port to be omitted with address,
> > and I think the new code is clearer. Or at least unclear in an
> > unrelated way :/.
> >
> > > I think
> > > it's nice to have for users, but it looks inconsistent here, so maybe
> > > you could add a comment before that, say:
> > >
> > > /* Accept :/PORT as well as :ADDR/PORT */
> > >
> > > > + p = tgtspec; /* No target address, backtrack */
> > > > +
> > > > if (!parse_port_range(&p, &tr))
> > > > return false;
> > > > } else {
> > > > @@ -492,6 +512,8 @@ static bool parse_port_chunk(const char **cursor,
> > > >
> > > > *kindp = kind;
> > > > *lrange = lr;
> > > > + if (taddr)
> > > > + *taddr = taddr_tmp;
> > > > if (trange)
> > > > *trange = tr;
> > > > *cursor = p;
> > > > @@ -561,7 +583,7 @@ static void fwd_rule_parse_ports(struct fwd_table *fwd, bool del, uint8_t proto,
> > > > /* Consider excluded ranges and "auto" in the first pass */
> > > > p = spec;
> > > > do {
> > > > - if (!parse_port_chunk(&p, &kind, &lrange, NULL))
> > > > + if (!parse_port_chunk(&p, &kind, &lrange, NULL, NULL))
> > > > goto bad;
> > > >
> > > > switch (kind) {
> > > > @@ -586,8 +608,9 @@ static void fwd_rule_parse_ports(struct fwd_table *fwd, bool del, uint8_t proto,
> > > > p = spec;
> > > > do {
> > > > struct port_range trange;
> > > > + union inany_addr taddr;
> > > >
> > > > - if (!parse_port_chunk(&p, &kind, &lrange, &trange))
> > > > + if (!parse_port_chunk(&p, &kind, &lrange, &taddr, &trange))
> > > > goto bad;
> > > >
> > > > switch (kind) {
> > > > @@ -604,7 +627,8 @@ static void fwd_rule_parse_ports(struct fwd_table *fwd, bool del, uint8_t proto,
> > > >
> > > > fwd_rule_range_except(fwd, del, proto, addr, ifname,
> > > > lrange.first, lrange.last,
> > > > - exclude, trange.first, flags);
> > > > + exclude, &taddr, trange.first,
> > > > + flags);
> > > > break;
> > > > default:
> > > > goto bad;
> > > > @@ -620,7 +644,7 @@ static void fwd_rule_parse_ports(struct fwd_table *fwd, bool del, uint8_t proto,
> > > >
> > > > fwd_rule_range_except(fwd, del, proto, addr, ifname,
> > > > 1, NUM_PORTS - 1, exclude,
> > > > - 1, flags | FWD_WEAK);
> > > > + NULL, 1, flags | FWD_WEAK);
> > > > }
> > > > return;
> > > > bad:
> > >
> > > The rest of the series looks good to me, but I didn't test things at
> > > all. By the way, man page and usage changes for 3/3 are missing.
> >
> > Ugh, yeah, I belatedly realised that.
> >
> > > I haven't seen anything preventing mapping between IPv4 and IPv6, but I
> > > guess I missed something. I actually think it would be a nice feature
> > > but I guess it needs some more effort to properly support it.
> >
> > Oh sod, good point. I forgot to add that check. I think we need it
> > for now, because I'm pretty sure it won't work end to end yet.
>
> I guess probably worth a quick check, I wouldn't be surprised if things
> actually kind of work for TCP.
Yes, but there are a lot of paths to check, so I'd prefer to
explicitly exclude this for the first spin. I've now added that,
though it has the mildly unfortunate side effect that it's now
(usually) impossible to specify a target address without listening
address (Because -t 5000:192.0.2.1 means */5000:192.0.2.1/5000.. and
since * listens on IPv6 it would mean family translation in at least
some cases). Rechecking and relaxing this is high on the list of
followons.
--
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
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2026-07-02 6:31 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-01 7:08 [PATCH 0/3] RFC: Target address mapping David Gibson
2026-07-01 7:08 ` [PATCH 1/3] fwd_rule: Parse target adddresses for forwarding rules David Gibson
2026-07-02 4:58 ` Stefano Brivio
2026-07-02 5:21 ` David Gibson
2026-07-02 5:31 ` Stefano Brivio
2026-07-02 6:08 ` David Gibson [this message]
2026-07-01 7:08 ` [PATCH 2/3] fwd: Clarify semantics of --host-lo-to-ns-lo David Gibson
2026-07-01 7:08 ` [PATCH 3/3] fwd, fwd_rule: Implement configurable target address mapping David Gibson
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=akYAcEF3l5xdPiHS@zatzit \
--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).