netfilter: ipset: Fix hash type expire: release empty hash bucket block
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Sat, 7 Nov 2015 10:24:51 +0000 (11:24 +0100)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Sat, 7 Nov 2015 10:28:49 +0000 (11:28 +0100)
When all entries are expired/all slots are empty, release the bucket.

Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
net/netfilter/ipset/ip_set_hash_gen.h

index fa4f6374bb734b44fee49097dc87e3d07ec6d56f..e5336ab36d679d707704a3988baec47360e6b9a4 100644 (file)
@@ -476,7 +476,7 @@ static void
 mtype_expire(struct ip_set *set, struct htype *h, u8 nets_length, size_t dsize)
 {
        struct htable *t;
-       struct hbucket *n;
+       struct hbucket *n, *tmp;
        struct mtype_elem *data;
        u32 i, j, d;
 #ifdef IP_SET_HASH_WITH_NETS
@@ -511,9 +511,14 @@ mtype_expire(struct ip_set *set, struct htype *h, u8 nets_length, size_t dsize)
                        }
                }
                if (d >= AHASH_INIT_SIZE) {
-                       struct hbucket *tmp = kzalloc(sizeof(*tmp) +
-                                       (n->size - AHASH_INIT_SIZE) * dsize,
-                                       GFP_ATOMIC);
+                       if (d >= n->size) {
+                               rcu_assign_pointer(hbucket(t, i), NULL);
+                               kfree_rcu(n, rcu);
+                               continue;
+                       }
+                       tmp = kzalloc(sizeof(*tmp) +
+                                     (n->size - AHASH_INIT_SIZE) * dsize,
+                                     GFP_ATOMIC);
                        if (!tmp)
                                /* Still try to delete expired elements */
                                continue;