netfilter: nft_connlimit: move stateful fields out of expression data
authorPablo Neira Ayuso <pablo@netfilter.org>
Sun, 9 Jan 2022 16:11:13 +0000 (17:11 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sun, 9 Jan 2022 22:35:16 +0000 (23:35 +0100)
In preparation for the rule blob representation.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nft_connlimit.c

index 7d0761f..58dcafe 100644 (file)
@@ -14,7 +14,7 @@
 #include <net/netfilter/nf_conntrack_zones.h>
 
 struct nft_connlimit {
-       struct nf_conncount_list        list;
+       struct nf_conncount_list        *list;
        u32                             limit;
        bool                            invert;
 };
@@ -43,12 +43,12 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv,
                return;
        }
 
-       if (nf_conncount_add(nft_net(pkt), &priv->list, tuple_ptr, zone)) {
+       if (nf_conncount_add(nft_net(pkt), priv->list, tuple_ptr, zone)) {
                regs->verdict.code = NF_DROP;
                return;
        }
 
-       count = priv->list.count;
+       count = priv->list->count;
 
        if ((count > priv->limit) ^ priv->invert) {
                regs->verdict.code = NFT_BREAK;
@@ -76,7 +76,11 @@ static int nft_connlimit_do_init(const struct nft_ctx *ctx,
                        invert = true;
        }
 
-       nf_conncount_list_init(&priv->list);
+       priv->list = kmalloc(sizeof(*priv->list), GFP_KERNEL);
+       if (!priv->list)
+               return -ENOMEM;
+
+       nf_conncount_list_init(priv->list);
        priv->limit     = limit;
        priv->invert    = invert;
 
@@ -87,7 +91,8 @@ static void nft_connlimit_do_destroy(const struct nft_ctx *ctx,
                                     struct nft_connlimit *priv)
 {
        nf_ct_netns_put(ctx->net, ctx->family);
-       nf_conncount_cache_free(&priv->list);
+       nf_conncount_cache_free(priv->list);
+       kfree(priv->list);
 }
 
 static int nft_connlimit_do_dump(struct sk_buff *skb,
@@ -200,7 +205,11 @@ static int nft_connlimit_clone(struct nft_expr *dst, const struct nft_expr *src)
        struct nft_connlimit *priv_dst = nft_expr_priv(dst);
        struct nft_connlimit *priv_src = nft_expr_priv(src);
 
-       nf_conncount_list_init(&priv_dst->list);
+       priv_dst->list = kmalloc(sizeof(*priv_dst->list), GFP_ATOMIC);
+       if (priv_dst->list)
+               return -ENOMEM;
+
+       nf_conncount_list_init(priv_dst->list);
        priv_dst->limit  = priv_src->limit;
        priv_dst->invert = priv_src->invert;
 
@@ -212,7 +221,8 @@ static void nft_connlimit_destroy_clone(const struct nft_ctx *ctx,
 {
        struct nft_connlimit *priv = nft_expr_priv(expr);
 
-       nf_conncount_cache_free(&priv->list);
+       nf_conncount_cache_free(priv->list);
+       kfree(priv->list);
 }
 
 static bool nft_connlimit_gc(struct net *net, const struct nft_expr *expr)
@@ -221,7 +231,7 @@ static bool nft_connlimit_gc(struct net *net, const struct nft_expr *expr)
        bool ret;
 
        local_bh_disable();
-       ret = nf_conncount_gc_list(net, &priv->list);
+       ret = nf_conncount_gc_list(net, priv->list);
        local_bh_enable();
 
        return ret;