From: Jozsef Kadlecsik <kadlec@netfilter.org>
To: Vishwanath Pai <vpai@akamai.com>
Cc: pablo@netfilter.org, fw@strlen.de, johunt@akamai.com,
netfilter-devel@vger.kernel.org
Subject: Re: [PATCH] netfilter: ipset: ipset list may return wrong member count on bitmap types
Date: Tue, 12 Jul 2022 23:06:14 +0200 (CEST) [thread overview]
Message-ID: <73de8f7a-365-ef8c-77fa-52c6ad94cde@netfilter.org> (raw)
In-Reply-To: <20220629212109.3045794-1-vpai@akamai.com>
Hi Vishwanath,
On Wed, 29 Jun 2022, Vishwanath Pai wrote:
> We fixed a similar problem before in commit 7f4f7dd4417d ("netfilter:
> ipset: ipset list may return wrong member count for set with timeout").
> The same issue exists in ip_set_bitmap_gen.h as well.
Could you rework the patch to solve the issue the same way as for the hash
types (i.e. scanning the set without locking) like in the commit
33f08da28324 (netfilter: ipset: Fix "INFO: rcu detected stall in hash_xxx"
reports)? I know the bitmap types have got a limited size but it'd be
great if the general method would be the same across the different types.
Best regards,
Jozsef
> Test case:
>
> $ ipset create test bitmap:ip range 10.0.0.0/8 netmask 24 timeout 5
> $ ipset add test 10.0.0.0
> $ ipset add test 10.255.255.255
> $ sleep 5s
>
> $ ipset list test
> Name: test
> Type: bitmap:ip
> Revision: 3
> Header: range 10.0.0.0-10.255.255.255 netmask 24 timeout 5
> Size in memory: 532568
> References: 0
> Number of entries: 2
> Members:
>
> We return "Number of entries: 2" but no members are listed. That is
> because when we run mtype_head the garbage collector hasn't run yet, but
> mtype_list checks and cleans up members with expired timeout. To avoid
> this we can run mtype_expire before printing the number of elements in
> mytype_head().
>
> Reviewed-by: Joshua Hunt <johunt@akamai.com>
> Signed-off-by: Vishwanath Pai <vpai@akamai.com>
> ---
> net/netfilter/ipset/ip_set_bitmap_gen.h | 46 ++++++++++++++++++-------
> 1 file changed, 34 insertions(+), 12 deletions(-)
>
> diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h
> index 26ab0e9612d8..dd871305bd6e 100644
> --- a/net/netfilter/ipset/ip_set_bitmap_gen.h
> +++ b/net/netfilter/ipset/ip_set_bitmap_gen.h
> @@ -28,6 +28,7 @@
> #define mtype_del IPSET_TOKEN(MTYPE, _del)
> #define mtype_list IPSET_TOKEN(MTYPE, _list)
> #define mtype_gc IPSET_TOKEN(MTYPE, _gc)
> +#define mtype_expire IPSET_TOKEN(MTYPE, _expire)
> #define mtype MTYPE
>
> #define get_ext(set, map, id) ((map)->extensions + ((set)->dsize * (id)))
> @@ -88,13 +89,44 @@ mtype_memsize(const struct mtype *map, size_t dsize)
> map->elements * dsize;
> }
>
> +/* We should grab set->lock before calling this function */
> +static void
> +mtype_expire(struct ip_set *set)
> +{
> + struct mtype *map = set->data;
> + void *x;
> + u32 id;
> +
> + for (id = 0; id < map->elements; id++)
> + if (mtype_gc_test(id, map, set->dsize)) {
> + x = get_ext(set, map, id);
> + if (ip_set_timeout_expired(ext_timeout(x, set))) {
> + clear_bit(id, map->members);
> + ip_set_ext_destroy(set, x);
> + set->elements--;
> + }
> + }
> +}
> +
> static int
> mtype_head(struct ip_set *set, struct sk_buff *skb)
> {
> const struct mtype *map = set->data;
> struct nlattr *nested;
> - size_t memsize = mtype_memsize(map, set->dsize) + set->ext_size;
> + size_t memsize;
> +
> + /* If any members have expired, set->elements will be wrong,
> + * mytype_expire function will update it with the right count.
> + * set->elements can still be incorrect in the case of a huge set
> + * because elements can timeout during set->list().
> + */
> + if (SET_WITH_TIMEOUT(set)) {
> + spin_lock_bh(&set->lock);
> + mtype_expire(set);
> + spin_unlock_bh(&set->lock);
> + }
>
> + memsize = mtype_memsize(map, set->dsize) + set->ext_size;
> nested = nla_nest_start(skb, IPSET_ATTR_DATA);
> if (!nested)
> goto nla_put_failure;
> @@ -266,22 +298,12 @@ mtype_gc(struct timer_list *t)
> {
> struct mtype *map = from_timer(map, t, gc);
> struct ip_set *set = map->set;
> - void *x;
> - u32 id;
>
> /* We run parallel with other readers (test element)
> * but adding/deleting new entries is locked out
> */
> spin_lock_bh(&set->lock);
> - for (id = 0; id < map->elements; id++)
> - if (mtype_gc_test(id, map, set->dsize)) {
> - x = get_ext(set, map, id);
> - if (ip_set_timeout_expired(ext_timeout(x, set))) {
> - clear_bit(id, map->members);
> - ip_set_ext_destroy(set, x);
> - set->elements--;
> - }
> - }
> + mtype_expire(set);
> spin_unlock_bh(&set->lock);
>
> map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
> --
> 2.25.1
>
>
-
E-mail : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.hu
PGP key : https://wigner.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics
H-1525 Budapest 114, POB. 49, Hungary
next prev parent reply other threads:[~2022-07-12 21:06 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-29 21:21 [PATCH] netfilter: ipset: ipset list may return wrong member count on bitmap types Vishwanath Pai
2022-06-29 21:21 ` [PATCH] netfilter: ipset: regression in ip_set_hash_ip.c Vishwanath Pai
2022-07-12 21:42 ` Jozsef Kadlecsik
2022-07-13 20:07 ` Vishwanath Pai
2022-06-29 21:21 ` [PATCH] netfilter: ipset: Add support for new bitmask parameter Vishwanath Pai
2022-07-12 22:45 ` Jozsef Kadlecsik
2022-07-18 15:18 ` Vishwanath Pai
2022-07-12 21:06 ` Jozsef Kadlecsik [this message]
2022-07-14 0:08 ` [PATCH] netfilter: ipset: ipset list may return wrong member count on bitmap types Vishwanath Pai
2022-07-14 6:08 ` Jozsef Kadlecsik
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=73de8f7a-365-ef8c-77fa-52c6ad94cde@netfilter.org \
--to=kadlec@netfilter.org \
--cc=fw@strlen.de \
--cc=johunt@akamai.com \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
--cc=vpai@akamai.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 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).