]> granicus.if.org Git - ipset/commitdiff
Support updating extensions when the set is full
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Tue, 23 Sep 2014 09:10:12 +0000 (11:10 +0200)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Tue, 23 Sep 2014 09:10:12 +0000 (11:10 +0200)
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 netfilter bugzilla id 880.)

kernel/net/netfilter/ipset/ip_set_hash_gen.h
tests/hash:mac.t
tests/hash:mac.t.list3 [new file with mode: 0644]

index 1ab33395506a6f0ae60e39a9f41f8d693961e064..a3c9fb445e24cd1e26554deb999eaaa6d7be3b68 100644 (file)
@@ -633,29 +633,6 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
        bool flag_exist = flags & IPSET_FLAG_EXIST;
        u32 key, multi = 0;
 
-       if (h->elements >= h->maxelem && SET_WITH_FORCEADD(set)) {
-               rcu_read_lock_bh();
-               t = rcu_dereference_bh(h->table);
-               key = HKEY(value, h->initval, t->htable_bits);
-               n = hbucket(t,key);
-               if (n->pos) {
-                       /* Choosing the first entry in the array to replace */
-                       j = 0;
-                       goto reuse_slot;
-               }
-               rcu_read_unlock_bh();
-       }
-       if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem)
-               /* FIXME: when set is full, we slow down here */
-               mtype_expire(set, h, NLEN(set->family), set->dsize);
-
-       if (h->elements >= h->maxelem) {
-               if (net_ratelimit())
-                       pr_warn("Set %s is full, maxelem %u reached\n",
-                               set->name, h->maxelem);
-               return -IPSET_ERR_HASH_FULL;
-       }
-
        rcu_read_lock_bh();
        t = rcu_dereference_bh(h->table);
        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,
                    j != AHASH_MAX(h) + 1)
                        j = i;
        }
+       if (h->elements >= h->maxelem && SET_WITH_FORCEADD(set) && n->pos) {
+               /* Choosing the first entry in the array to replace */
+               j = 0;
+               goto reuse_slot;
+       }
+       if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem)
+               /* FIXME: when set is full, we slow down here */
+               mtype_expire(set, h, NLEN(set->family), set->dsize);
+
+       if (h->elements >= h->maxelem) {
+               if (net_ratelimit())
+                       pr_warn("Set %s is full, maxelem %u reached\n",
+                               set->name, h->maxelem);
+               ret = -IPSET_ERR_HASH_FULL;
+               goto out;
+       }
+
 reuse_slot:
        if (j != AHASH_MAX(h) + 1) {
                /* Fill out reused slot */
index 25739da88b0faf13e3612baa26c8a16973138e27..f7023d0e6a095308e92b2ebe1bfa3cf896b37e30 100644 (file)
 0 diff -u -I 'Size in memory.*' .foo hash:mac.t.list1
 # MAC: Destroy test set
 0 ipset -X test
+# MAC: Create a set with small maxelem parameter
+0 ipset n test hash:mac maxelem 2 skbinfo
+# MAC: Add first element
+0 ipset a test 1:2:3:4:5:6 skbprio 1:10
+# MAC: Add second element
+0 ipset a test 1:2:3:4:5:7 skbprio 1:11
+# MAC: Add third element
+1 ipset a test 1:2:3:4:5:8 skbprio 1:12
+# MAC: Add second element again
+1 ipset a test 1:2:3:4:5:7 skbprio 1:11
+# MAC: Add second element with another extension value
+0 ipset -! a test 1:2:3:4:5:7 skbprio 1:12 skbqueue 8
+# MAC: List set
+0 ipset -L test 2>/dev/null | grep -v Revision: > .foo0 && ./sort.sh .foo0
+# MAC: Check listing
+0 diff -u -I 'Size in memory.*' .foo hash:mac.t.list3
+# MAC: Destroy test set
+0 ipset x test
 # eof
diff --git a/tests/hash:mac.t.list3 b/tests/hash:mac.t.list3
new file mode 100644 (file)
index 0000000..2253a34
--- /dev/null
@@ -0,0 +1,8 @@
+Name: test
+Type: hash:mac
+Header: hashsize 1024 maxelem 2 skbinfo
+Size in memory: 16792
+References: 0
+Members:
+01:02:03:04:05:06 skbprio 1:10
+01:02:03:04:05:07 skbprio 1:12 skbqueue 8