]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
netfilter: move nf_ct_netns_get out of nf_conncount_init
authorXin Long <lucien.xin@gmail.com>
Thu, 18 Jul 2024 02:09:44 +0000 (22:09 -0400)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 19 Aug 2024 16:44:51 +0000 (18:44 +0200)
This patch is to move nf_ct_netns_get() out of nf_conncount_init()
and let the consumers of nf_conncount decide if they want to turn
on netfilter conntrack.

It makes nf_conncount more flexible to be used in other places and
avoids netfilter conntrack turned on when using it in openvswitch
conntrack.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Reviewed-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/netfilter/nf_conntrack_count.h
net/netfilter/nf_conncount.c
net/netfilter/xt_connlimit.c
net/openvswitch/conntrack.c

index e227d997fc71667043c7aaf6668b8b2b3c1ee25b..1b58b5b91ff6a48f2dba2608f53477b32c546c80 100644 (file)
@@ -15,10 +15,8 @@ struct nf_conncount_list {
        unsigned int count;     /* length of list */
 };
 
-struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
-                                           unsigned int keylen);
-void nf_conncount_destroy(struct net *net, unsigned int family,
-                         struct nf_conncount_data *data);
+struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
+void nf_conncount_destroy(struct net *net, struct nf_conncount_data *data);
 
 unsigned int nf_conncount_count(struct net *net,
                                struct nf_conncount_data *data,
index 34ba14e59e95a81ff6b6c6c64f12b70ebc907b9d..4890af4dc263fdd36a463536640208ee27f10768 100644 (file)
@@ -522,11 +522,10 @@ unsigned int nf_conncount_count(struct net *net,
 }
 EXPORT_SYMBOL_GPL(nf_conncount_count);
 
-struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
-                                           unsigned int keylen)
+struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen)
 {
        struct nf_conncount_data *data;
-       int ret, i;
+       int i;
 
        if (keylen % sizeof(u32) ||
            keylen / sizeof(u32) > MAX_KEYLEN ||
@@ -539,12 +538,6 @@ struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family
        if (!data)
                return ERR_PTR(-ENOMEM);
 
-       ret = nf_ct_netns_get(net, family);
-       if (ret < 0) {
-               kfree(data);
-               return ERR_PTR(ret);
-       }
-
        for (i = 0; i < ARRAY_SIZE(data->root); ++i)
                data->root[i] = RB_ROOT;
 
@@ -581,13 +574,11 @@ static void destroy_tree(struct rb_root *r)
        }
 }
 
-void nf_conncount_destroy(struct net *net, unsigned int family,
-                         struct nf_conncount_data *data)
+void nf_conncount_destroy(struct net *net, struct nf_conncount_data *data)
 {
        unsigned int i;
 
        cancel_work_sync(&data->gc_work);
-       nf_ct_netns_put(net, family);
 
        for (i = 0; i < ARRAY_SIZE(data->root); ++i)
                destroy_tree(&data->root[i]);
index 5d04ef80a61dcf65d06a263e486fe7bb4060938f..0e762277bcf8f95ec0c9e35ec645f6e7af048609 100644 (file)
@@ -86,6 +86,7 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par)
 {
        struct xt_connlimit_info *info = par->matchinfo;
        unsigned int keylen;
+       int ret;
 
        keylen = sizeof(u32);
        if (par->family == NFPROTO_IPV6)
@@ -93,8 +94,17 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par)
        else
                keylen += sizeof(struct in_addr);
 
+       ret = nf_ct_netns_get(par->net, par->family);
+       if (ret < 0) {
+               pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
+                                   par->family);
+               return ret;
+       }
+
        /* init private data */
-       info->data = nf_conncount_init(par->net, par->family, keylen);
+       info->data = nf_conncount_init(par->net, keylen);
+       if (IS_ERR(info->data))
+               nf_ct_netns_put(par->net, par->family);
 
        return PTR_ERR_OR_ZERO(info->data);
 }
@@ -103,7 +113,8 @@ static void connlimit_mt_destroy(const struct xt_mtdtor_param *par)
 {
        const struct xt_connlimit_info *info = par->matchinfo;
 
-       nf_conncount_destroy(par->net, par->family, info->data);
+       nf_conncount_destroy(par->net, info->data);
+       nf_ct_netns_put(par->net, par->family);
 }
 
 static struct xt_match connlimit_mt_reg __read_mostly = {
index a3da5ee34f92dbfd351b22a7fe503d06702d4dc9..3bb4810234aac2949fbc624b81038977de3bd493 100644 (file)
@@ -1608,8 +1608,7 @@ static int ovs_ct_limit_init(struct net *net, struct ovs_net *ovs_net)
        for (i = 0; i < CT_LIMIT_HASH_BUCKETS; i++)
                INIT_HLIST_HEAD(&ovs_net->ct_limit_info->limits[i]);
 
-       ovs_net->ct_limit_info->data =
-               nf_conncount_init(net, NFPROTO_INET, sizeof(u32));
+       ovs_net->ct_limit_info->data = nf_conncount_init(net, sizeof(u32));
 
        if (IS_ERR(ovs_net->ct_limit_info->data)) {
                err = PTR_ERR(ovs_net->ct_limit_info->data);
@@ -1626,7 +1625,7 @@ static void ovs_ct_limit_exit(struct net *net, struct ovs_net *ovs_net)
        const struct ovs_ct_limit_info *info = ovs_net->ct_limit_info;
        int i;
 
-       nf_conncount_destroy(net, NFPROTO_INET, info->data);
+       nf_conncount_destroy(net, info->data);
        for (i = 0; i < CT_LIMIT_HASH_BUCKETS; ++i) {
                struct hlist_head *head = &info->limits[i];
                struct ovs_ct_limit *ct_limit;