netfilter: conntrack: allow increasing bucket size via sysctl too
[deliverable/linux.git] / net / netfilter / nf_conntrack_core.c
index a459176c3253f7491b30de43f03c8361651abebf..e17d5c7faca0b3310498ff5239061d9ee244becb 100644 (file)
@@ -1595,24 +1595,14 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
 }
 EXPORT_SYMBOL_GPL(nf_ct_alloc_hashtable);
 
-int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
+int nf_conntrack_hash_resize(unsigned int hashsize)
 {
-       int i, bucket, rc;
-       unsigned int hashsize, old_size;
+       int i, bucket;
+       unsigned int old_size;
        struct hlist_nulls_head *hash, *old_hash;
        struct nf_conntrack_tuple_hash *h;
        struct nf_conn *ct;
 
-       if (current->nsproxy->net_ns != &init_net)
-               return -EOPNOTSUPP;
-
-       /* On boot, we can set this without any fancy locking. */
-       if (!nf_conntrack_htable_size)
-               return param_set_uint(val, kp);
-
-       rc = kstrtouint(val, 0, &hashsize);
-       if (rc)
-               return rc;
        if (!hashsize)
                return -EINVAL;
 
@@ -1620,6 +1610,12 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
        if (!hash)
                return -ENOMEM;
 
+       old_size = nf_conntrack_htable_size;
+       if (old_size == hashsize) {
+               nf_ct_free_hashtable(hash, hashsize);
+               return 0;
+       }
+
        local_bh_disable();
        nf_conntrack_all_lock();
        write_seqcount_begin(&nf_conntrack_generation);
@@ -1655,6 +1651,25 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
        nf_ct_free_hashtable(old_hash, old_size);
        return 0;
 }
+
+int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
+{
+       unsigned int hashsize;
+       int rc;
+
+       if (current->nsproxy->net_ns != &init_net)
+               return -EOPNOTSUPP;
+
+       /* On boot, we can set this without any fancy locking. */
+       if (!nf_conntrack_htable_size)
+               return param_set_uint(val, kp);
+
+       rc = kstrtouint(val, 0, &hashsize);
+       if (rc)
+               return rc;
+
+       return nf_conntrack_hash_resize(hashsize);
+}
 EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize);
 
 module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint,
This page took 0.027596 seconds and 5 git commands to generate.