@@ -18,7 +18,7 @@ static DEFINE_PER_CPU(struct rnd_state, nft_numgen_prandom_state);
1818struct nft_ng_inc {
1919 u8 dreg ;
2020 u32 modulus ;
21- atomic_t counter ;
21+ atomic_t * counter ;
2222 u32 offset ;
2323};
2424
@@ -27,9 +27,9 @@ static u32 nft_ng_inc_gen(struct nft_ng_inc *priv)
2727 u32 nval , oval ;
2828
2929 do {
30- oval = atomic_read (& priv -> counter );
30+ oval = atomic_read (priv -> counter );
3131 nval = (oval + 1 < priv -> modulus ) ? oval + 1 : 0 ;
32- } while (atomic_cmpxchg (& priv -> counter , oval , nval ) != oval );
32+ } while (atomic_cmpxchg (priv -> counter , oval , nval ) != oval );
3333
3434 return nval + priv -> offset ;
3535}
@@ -55,6 +55,7 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
5555 const struct nlattr * const tb [])
5656{
5757 struct nft_ng_inc * priv = nft_expr_priv (expr );
58+ int err ;
5859
5960 if (tb [NFTA_NG_OFFSET ])
6061 priv -> offset = ntohl (nla_get_be32 (tb [NFTA_NG_OFFSET ]));
@@ -66,10 +67,22 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
6667 if (priv -> offset + priv -> modulus - 1 < priv -> offset )
6768 return - EOVERFLOW ;
6869
69- atomic_set (& priv -> counter , priv -> modulus - 1 );
70+ priv -> counter = kmalloc (sizeof (* priv -> counter ), GFP_KERNEL );
71+ if (!priv -> counter )
72+ return - ENOMEM ;
7073
71- return nft_parse_register_store (ctx , tb [NFTA_NG_DREG ], & priv -> dreg ,
72- NULL , NFT_DATA_VALUE , sizeof (u32 ));
74+ atomic_set (priv -> counter , priv -> modulus - 1 );
75+
76+ err = nft_parse_register_store (ctx , tb [NFTA_NG_DREG ], & priv -> dreg ,
77+ NULL , NFT_DATA_VALUE , sizeof (u32 ));
78+ if (err < 0 )
79+ goto err ;
80+
81+ return 0 ;
82+ err :
83+ kfree (priv -> counter );
84+
85+ return err ;
7386}
7487
7588static int nft_ng_dump (struct sk_buff * skb , enum nft_registers dreg ,
@@ -98,6 +111,14 @@ static int nft_ng_inc_dump(struct sk_buff *skb, const struct nft_expr *expr)
98111 priv -> offset );
99112}
100113
114+ static void nft_ng_inc_destroy (const struct nft_ctx * ctx ,
115+ const struct nft_expr * expr )
116+ {
117+ const struct nft_ng_inc * priv = nft_expr_priv (expr );
118+
119+ kfree (priv -> counter );
120+ }
121+
101122struct nft_ng_random {
102123 u8 dreg ;
103124 u32 modulus ;
@@ -157,6 +178,7 @@ static const struct nft_expr_ops nft_ng_inc_ops = {
157178 .size = NFT_EXPR_SIZE (sizeof (struct nft_ng_inc )),
158179 .eval = nft_ng_inc_eval ,
159180 .init = nft_ng_inc_init ,
181+ .destroy = nft_ng_inc_destroy ,
160182 .dump = nft_ng_inc_dump ,
161183};
162184
0 commit comments