From: "Kerin Millar" <kfm@plushkava.net>
To: Anton <anton.khazan@gmail.com>, netfilter@vger.kernel.org
Subject: Re: Is there an efficient way to delete multiple elements from a set?
Date: Wed, 31 Jan 2024 12:20:09 +0000 [thread overview]
Message-ID: <3cfd95bb-93ca-4f40-9e1e-bb2526789161@app.fastmail.com> (raw)
In-Reply-To: <CAJE3=wmAh5Ne9fWdrHOyZx9uuz+_g4+PhVXnfr+pS417mVWfhA@mail.gmail.com>
On Wed, 31 Jan 2024, at 8:14 AM, Anton wrote:
> Hello, I've been experimenting with nftables sets for the purpose of
> geoip blocking. Let's say I'd like to add ip blocks for multiple
> countries to a blacklist or to a whitelist. Perhaps the most efficient
> way to do that would be by combining all required ip blocks in one set
> (for each family). However since country ip blocks are a moving
> target, I would need to regularly refresh parts of that set. My idea
> was to delete all ip addresses corresponding to an ip block from the
> set and then add the updated ip block. The problem is, this is very
> slow. While adding an ip block takes (in my VM) 0.09s, deleting all
> ip's from that same block takes 14.5s.
>
> This is how I'm doing the deletion and the time measurement:
> printf '%s\n' "delete element inet test testset { $(cat test.set) };"
> | /usr/bin/time -f %es nft -f -
>
> (the test.set file stores a comma-separated list of subnets)
>
> Is there a more efficient way to do this? I could of course flush the
> set and rebuild it every time I need to update some part of it, but I
> thought I'd ask before deciding to implement that.
Indeed there is. Your method isn't optimal because the command substitution causes the shell to needlessly assign memory for the sole purpose of containing the entirety of the output of cat(1). Further, cat(1) will have to complete before the printf builtin can even be executed, which defeats the asynchronicity of the pipeline. You should feed nft(8) with a command list instead.
{
printf 'delete element inet test testset { '
cat test.set
printf ' }'
} | nft -f -
If you would prefer to express it as a one-liner then you may, in which case you must also terminate each of the three commands in the { command list } with a semicolon.
--
Kerin Millar
next prev parent reply other threads:[~2024-01-31 12:20 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-31 8:14 Is there an efficient way to delete multiple elements from a set? Anton
2024-01-31 8:21 ` Reindl Harald
2024-01-31 8:27 ` Anton
2024-01-31 12:20 ` Kerin Millar [this message]
2024-01-31 22:13 ` Anton
2024-01-31 22:39 ` Kerin Millar
2024-01-31 23:11 ` Anton
2024-02-01 9:41 ` Pablo Neira Ayuso
2024-02-01 9:42 ` Pablo Neira Ayuso
2024-02-01 10:24 ` Jozsef Kadlecsik
2024-02-01 12:20 ` Kerin Millar
2024-02-02 0:36 ` Anton
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=3cfd95bb-93ca-4f40-9e1e-bb2526789161@app.fastmail.com \
--to=kfm@plushkava.net \
--cc=anton.khazan@gmail.com \
--cc=netfilter@vger.kernel.org \
/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