All of lore.kernel.org
 help / color / mirror / Atom feed
From: Phil Sutter <phil@nwl.cc>
To: Stefano Brivio <sbrivio@redhat.com>
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:58:07 +0100	[thread overview]
Message-ID: <20191121175807.GF3074@orbyte.nwl.cc> (raw)
In-Reply-To: <20191121180938.381eabab@redhat.com>

Hi,

On Thu, Nov 21, 2019 at 06:09:38PM +0100, Stefano Brivio wrote:
> 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.

Yes, I overdid it a bit there trying to have a single call to
netlink_export_pad(). You found a good middle-ground!

[...]
> > > > 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 suspected that already. :)

> 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.

*Obviously* my algorithm assumed pass-by-value. ;)

Thanks, Phil

  reply	other threads:[~2019-11-21 17:58 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
2019-11-21 17:58           ` Phil Sutter [this message]
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=20191121175807.GF3074@orbyte.nwl.cc \
    --to=phil@nwl.cc \
    --cc=eric@garver.life \
    --cc=fw@strlen.de \
    --cc=kadlec@blackhole.kfki.hu \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    --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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.