Skip to content

Commit 978d8f9

Browse files
Laura Garcia Liebanaummakynes
authored andcommitted
netfilter: nft_numgen: add map lookups for numgen random operations
This patch uses the map lookup already included to be applied for random number generation. Signed-off-by: Laura Garcia Liebana <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent e65eebe commit 978d8f9

File tree

1 file changed

+72
-4
lines changed

1 file changed

+72
-4
lines changed

net/netfilter/nft_numgen.c

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,18 +166,43 @@ struct nft_ng_random {
166166
enum nft_registers dreg:8;
167167
u32 modulus;
168168
u32 offset;
169+
struct nft_set *map;
169170
};
170171

172+
static u32 nft_ng_random_gen(struct nft_ng_random *priv)
173+
{
174+
struct rnd_state *state = this_cpu_ptr(&nft_numgen_prandom_state);
175+
176+
return reciprocal_scale(prandom_u32_state(state), priv->modulus) +
177+
priv->offset;
178+
}
179+
171180
static void nft_ng_random_eval(const struct nft_expr *expr,
172181
struct nft_regs *regs,
173182
const struct nft_pktinfo *pkt)
174183
{
175184
struct nft_ng_random *priv = nft_expr_priv(expr);
176-
struct rnd_state *state = this_cpu_ptr(&nft_numgen_prandom_state);
177-
u32 val;
178185

179-
val = reciprocal_scale(prandom_u32_state(state), priv->modulus);
180-
regs->data[priv->dreg] = val + priv->offset;
186+
regs->data[priv->dreg] = nft_ng_random_gen(priv);
187+
}
188+
189+
static void nft_ng_random_map_eval(const struct nft_expr *expr,
190+
struct nft_regs *regs,
191+
const struct nft_pktinfo *pkt)
192+
{
193+
struct nft_ng_random *priv = nft_expr_priv(expr);
194+
const struct nft_set *map = priv->map;
195+
const struct nft_set_ext *ext;
196+
u32 result;
197+
bool found;
198+
199+
result = nft_ng_random_gen(priv);
200+
found = map->ops->lookup(nft_net(pkt), map, &result, &ext);
201+
if (!found)
202+
return;
203+
204+
nft_data_copy(&regs->data[priv->dreg],
205+
nft_set_ext_data(ext), map->dlen);
181206
}
182207

183208
static int nft_ng_random_init(const struct nft_ctx *ctx,
@@ -204,6 +229,23 @@ static int nft_ng_random_init(const struct nft_ctx *ctx,
204229
NFT_DATA_VALUE, sizeof(u32));
205230
}
206231

232+
static int nft_ng_random_map_init(const struct nft_ctx *ctx,
233+
const struct nft_expr *expr,
234+
const struct nlattr * const tb[])
235+
{
236+
struct nft_ng_random *priv = nft_expr_priv(expr);
237+
u8 genmask = nft_genmask_next(ctx->net);
238+
239+
nft_ng_random_init(ctx, expr, tb);
240+
priv->map = nft_set_lookup_global(ctx->net, ctx->table,
241+
tb[NFTA_NG_SET_NAME],
242+
tb[NFTA_NG_SET_ID], genmask);
243+
if (IS_ERR(priv->map))
244+
return PTR_ERR(priv->map);
245+
246+
return 0;
247+
}
248+
207249
static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr)
208250
{
209251
const struct nft_ng_random *priv = nft_expr_priv(expr);
@@ -212,6 +254,22 @@ static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr)
212254
priv->offset);
213255
}
214256

257+
static int nft_ng_random_map_dump(struct sk_buff *skb,
258+
const struct nft_expr *expr)
259+
{
260+
const struct nft_ng_random *priv = nft_expr_priv(expr);
261+
262+
if (nft_ng_dump(skb, priv->dreg, priv->modulus,
263+
NFT_NG_RANDOM, priv->offset) ||
264+
nla_put_string(skb, NFTA_NG_SET_NAME, priv->map->name))
265+
goto nla_put_failure;
266+
267+
return 0;
268+
269+
nla_put_failure:
270+
return -1;
271+
}
272+
215273
static struct nft_expr_type nft_ng_type;
216274
static const struct nft_expr_ops nft_ng_inc_ops = {
217275
.type = &nft_ng_type,
@@ -237,6 +295,14 @@ static const struct nft_expr_ops nft_ng_random_ops = {
237295
.dump = nft_ng_random_dump,
238296
};
239297

298+
static const struct nft_expr_ops nft_ng_random_map_ops = {
299+
.type = &nft_ng_type,
300+
.size = NFT_EXPR_SIZE(sizeof(struct nft_ng_random)),
301+
.eval = nft_ng_random_map_eval,
302+
.init = nft_ng_random_map_init,
303+
.dump = nft_ng_random_map_dump,
304+
};
305+
240306
static const struct nft_expr_ops *
241307
nft_ng_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
242308
{
@@ -255,6 +321,8 @@ nft_ng_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
255321
return &nft_ng_inc_map_ops;
256322
return &nft_ng_inc_ops;
257323
case NFT_NG_RANDOM:
324+
if (tb[NFTA_NG_SET_NAME])
325+
return &nft_ng_random_map_ops;
258326
return &nft_ng_random_ops;
259327
}
260328

0 commit comments

Comments
 (0)