Message ID | 1505159560-13161-5-git-send-email-kadlec@blackhole.kfki.hu |
---|---|
State | Accepted |
Delegated to: | Pablo Neira |
Headers | show |
Series | [1/4] netfilter: ipset: Compress return logic | expand |
On Mon, Sep 11, 2017 at 09:52:40PM +0200, Jozsef Kadlecsik wrote: > From: Vishwanath Pai <vpai@akamai.com> > > Simple testcase: > > $ ipset create test hash:ip timeout 5 > $ ipset add test 1.2.3.4 > $ ipset add test 1.2.2.2 > $ sleep 5 > > $ ipset l > Name: test > Type: hash:ip > Revision: 5 > Header: family inet hashsize 1024 maxelem 65536 timeout 5 > Size in memory: 296 > References: 0 > Number of entries: 2 > Members: > > We return "Number of entries: 2" but no members are listed. That is > because mtype_list runs "ip_set_timeout_expired" and does not list the > expired entries, but set->elements is never upated (until mtype_gc > cleans it up later). Applied to nf.git. Thanks Jozsef. -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h index f236c0b..51063d9 100644 --- a/net/netfilter/ipset/ip_set_hash_gen.h +++ b/net/netfilter/ipset/ip_set_hash_gen.h @@ -1041,12 +1041,24 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext, static int mtype_head(struct ip_set *set, struct sk_buff *skb) { - const struct htype *h = set->data; + struct htype *h = set->data; const struct htable *t; struct nlattr *nested; size_t memsize; u8 htable_bits; + /* If any members have expired, set->elements will be wrong + * mytype_expire function will update it with the right count. + * we do not hold set->lock here, so grab it first. + * set->elements can still be incorrect in the case of a huge set, + * because elements might time out during the listing. + */ + if (SET_WITH_TIMEOUT(set)) { + spin_lock_bh(&set->lock); + mtype_expire(set, h); + spin_unlock_bh(&set->lock); + } + rcu_read_lock_bh(); t = rcu_dereference_bh_nfnl(h->table); memsize = mtype_ahash_memsize(h, t) + set->ext_size;