From: Stefano Brivio <sbrivio@redhat.com>
To: Phil Sutter <phil@nwl.cc>
Cc: "Pablo Neira Ayuso" <pablo@netfilter.org>,
netfilter-devel@vger.kernel.org,
"Florian Westphal" <fw@strlen.de>,
"Kadlecsik József" <kadlec@blackhole.kfki.hu>,
"Eric Garver" <eric@garver.life>
Subject: Re: [PATCH nft 2/3] src: Add support for concatenated set ranges
Date: Thu, 21 Nov 2019 18:09:38 +0100 [thread overview]
Message-ID: <20191121180938.381eabab@redhat.com> (raw)
In-Reply-To: <20191120125308.GK8016@orbyte.nwl.cc>
On Wed, 20 Nov 2019 13:53:08 +0100
Phil Sutter <phil@nwl.cc> wrote:
> On Wed, Nov 20, 2019 at 12:49:54PM +0100, Stefano Brivio wrote:
>
> > On Tue, 19 Nov 2019 23:12:38 +0100
> > Phil Sutter <phil@nwl.cc> wrote:
> [...]
>
> > So, the whole thing would look like (together with the other change
> > you suggest):
> >
> > --
> > static int netlink_gen_concat_data_expr(const struct expr *i,
> > unsigned char *data)
> > {
> > if (i->etype == EXPR_RANGE) {
> > const struct expr *e;
> >
> > if (i->flags & EXPR_F_INTERVAL_END)
> > e = i->right;
> > else
> > e = i->left;
> >
> > return netlink_export_pad(data, e->value, e);
> > }
> >
> > if (i->etype == EXPR_PREFIX) {
> > if (i->flags & EXPR_F_INTERVAL_END) {
> > int count;
> > mpz_t v;
> >
> > mpz_init_bitmask(v, i->len - i->prefix_len);
> > mpz_add(v, i->prefix->value, v);
> > count = netlink_export_pad(data, v, i);
> > mpz_clear(v);
> > return count;
> > }
> >
> > return netlink_export_pad(data, i->prefix->value, i);
> > }
> >
> > assert(i->etype == EXPR_VALUE);
> >
> > return netlink_export_pad(data, i->value, i);
> > }
>
> I would even:
>
> | static int
> | netlink_gen_concat_data_expr(const struct expr *i, unsigned char *data)
> | {
> | mpz_t *valp = NULL;
> |
> | switch (i->etype) {
> | case EXPR_RANGE:
> | i = (i->flags & EXPR_F_INTERVAL_END) ? i->right : i->left;
> | break;
> | case EXPR_PREFIX:
> | if (i->flags & EXPR_F_INTERVAL_END) {
> | int count;
> | mpz_t v;
> |
> | mpz_init_bitmask(v, i->len - i->prefix_len);
> | mpz_add(v, i->prefix->value, v);
> | count = netlink_export_pad(data, v, i);
> | mpz_clear(v);
> | return count;
> | }
> | valp = &i->prefix->value;
> | break;
> | case EXPR_VALUE:
> | break;
> | default:
> | BUG("invalid expression type '%s' in set", expr_ops(i)->name);
> | }
> |
> | return netlink_export_pad(data, valp ? *valp : i->value, i);
> | }
>
> But that's up to you. :)
I think it's nicer with a switch and that BUG() is more helpful than a
random assert, but I personally find that ternary condition on valp a
bit difficult to follow.
I'd recycle most of your function without that -- it's actually shorter
and still makes it clear enough what gets fed to netlink_export_pad().
Oh, and by the way, at this point we need to check flags on the 'key'
expression.
> > static void netlink_gen_concat_data(const struct expr *expr,
> > struct nft_data_linearize *nld)
> > {
> > unsigned int len = expr->len / BITS_PER_BYTE, offset = 0;
> > unsigned char data[len];
> > const struct expr *i;
> >
> > memset(data, 0, len);
> >
> > list_for_each_entry(i, &expr->expressions, list)
> > offset += netlink_gen_concat_data_expr(i, data + offset);
> >
> > memcpy(nld->value, data, len);
> > nld->len = len;
> > }
> > --
> >
> > Is that better?
>
> Looks great, thanks!
>
> [...]
>
> > > So this is the fifth copy of the same piece of code. :(
> > >
> > > Isn't there a better way to solve that?
> >
> > I couldn't think of any.
>
> I guess we would need an intermediate state which is 'multiton_rhs_expr
> DOT multiton_rhs_expr'. Might turn into a mess as well. :)
I just tried to add that, and kept losing myself in the middle of it.
It might be me, but it doesn't sound that promising when it comes to
readability later.
I guess we already have enough levels of indirection here -- I'd just
go with the compound_expr_alloc_or_add() you suggested.
> > > Intuitively, I would just:
> > >
> > > | int tmp = len;
> > > | while (start != end && !(start & 1) && (end & 1) && tmp) {
> > > | start >>= 1;
> > > | end >>= 1;
> > > | tmp--;
> > > | }
> > > | return (tmp && start == end) ? len - tmp : -1;
> > >
> > > Is that slow when dealing with gmp?
> >
> > I don't think so, it also avoid copies and allocations, while shifting
> > and setting bits have comparable complexities. I'd go with the gmp
> > version of this.
Actually, I need to preserve the original elements, so the two copies
are needed anyway -- other than that, I basically recycled your
function.
--
Stefano
next prev parent reply other threads:[~2019-11-21 17:09 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-19 1:07 [PATCH nft 0/3] Introduce support for concatenated ranges Stefano Brivio
2019-11-19 1:07 ` [PATCH nft 1/3] src: Add support for and export NFT_SET_SUBKEY attributes Stefano Brivio
2019-11-19 1:07 ` [PATCH nft 2/3] src: Add support for concatenated set ranges Stefano Brivio
2019-11-19 22:12 ` Phil Sutter
2019-11-20 11:49 ` Stefano Brivio
2019-11-20 12:53 ` Phil Sutter
2019-11-21 17:09 ` Stefano Brivio [this message]
2019-11-21 17:58 ` Phil Sutter
2019-11-19 1:07 ` [PATCH nft 3/3] tests: Introduce test for set with concatenated ranges 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=20191121180938.381eabab@redhat.com \
--to=sbrivio@redhat.com \
--cc=eric@garver.life \
--cc=fw@strlen.de \
--cc=kadlec@blackhole.kfki.hu \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
--cc=phil@nwl.cc \
/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.
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 NNTP newsgroup(s).