aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2014-11-30 13:56:52 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2014-12-03 06:43:34 -0500
commit86ac79c7bea1543423f96f388b7ac2e3acca66b3 (patch)
tree28d981e07fb25e3042e1dce20526fe1ee4c9adff
parent4338c5725920be301a02cad7907e98a076bf24b3 (diff)
netfilter: ipset: Support updating extensions when the set is full
When the set was full (hash type and maxelem reached), it was not possible to update the extension part of already existing elements. The patch removes this limitation. Fixes: https://bugzilla.netfilter.org/show_bug.cgi?id=880 Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/netfilter/ipset/ip_set_hash_gen.h40
1 files changed, 17 insertions, 23 deletions
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
index fee7c64e4dd1..a12ee045258b 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -633,29 +633,6 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
633 bool flag_exist = flags & IPSET_FLAG_EXIST; 633 bool flag_exist = flags & IPSET_FLAG_EXIST;
634 u32 key, multi = 0; 634 u32 key, multi = 0;
635 635
636 if (h->elements >= h->maxelem && SET_WITH_FORCEADD(set)) {
637 rcu_read_lock_bh();
638 t = rcu_dereference_bh(h->table);
639 key = HKEY(value, h->initval, t->htable_bits);
640 n = hbucket(t,key);
641 if (n->pos) {
642 /* Choosing the first entry in the array to replace */
643 j = 0;
644 goto reuse_slot;
645 }
646 rcu_read_unlock_bh();
647 }
648 if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem)
649 /* FIXME: when set is full, we slow down here */
650 mtype_expire(set, h, NLEN(set->family), set->dsize);
651
652 if (h->elements >= h->maxelem) {
653 if (net_ratelimit())
654 pr_warn("Set %s is full, maxelem %u reached\n",
655 set->name, h->maxelem);
656 return -IPSET_ERR_HASH_FULL;
657 }
658
659 rcu_read_lock_bh(); 636 rcu_read_lock_bh();
660 t = rcu_dereference_bh(h->table); 637 t = rcu_dereference_bh(h->table);
661 key = HKEY(value, h->initval, t->htable_bits); 638 key = HKEY(value, h->initval, t->htable_bits);
@@ -680,6 +657,23 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
680 j != AHASH_MAX(h) + 1) 657 j != AHASH_MAX(h) + 1)
681 j = i; 658 j = i;
682 } 659 }
660 if (h->elements >= h->maxelem && SET_WITH_FORCEADD(set) && n->pos) {
661 /* Choosing the first entry in the array to replace */
662 j = 0;
663 goto reuse_slot;
664 }
665 if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem)
666 /* FIXME: when set is full, we slow down here */
667 mtype_expire(set, h, NLEN(set->family), set->dsize);
668
669 if (h->elements >= h->maxelem) {
670 if (net_ratelimit())
671 pr_warn("Set %s is full, maxelem %u reached\n",
672 set->name, h->maxelem);
673 ret = -IPSET_ERR_HASH_FULL;
674 goto out;
675 }
676
683reuse_slot: 677reuse_slot:
684 if (j != AHASH_MAX(h) + 1) { 678 if (j != AHASH_MAX(h) + 1) {
685 /* Fill out reused slot */ 679 /* Fill out reused slot */