Skip to content

Commit

Permalink
netfilter: nft_numgen: add map lookups for numgen random operations
Browse files Browse the repository at this point in the history
This patch uses the map lookup already included to be applied
for random number generation.

Signed-off-by: Laura Garcia Liebana <nevola@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Laura Garcia Liebana authored and Pablo Neira Ayuso committed May 17, 2018
1 parent e65eebe commit 978d8f9
Showing 1 changed file with 72 additions and 4 deletions.
76 changes: 72 additions & 4 deletions net/netfilter/nft_numgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,18 +166,43 @@ struct nft_ng_random {
enum nft_registers dreg:8;
u32 modulus;
u32 offset;
struct nft_set *map;
};

static u32 nft_ng_random_gen(struct nft_ng_random *priv)
{
struct rnd_state *state = this_cpu_ptr(&nft_numgen_prandom_state);

return reciprocal_scale(prandom_u32_state(state), priv->modulus) +
priv->offset;
}

static void nft_ng_random_eval(const struct nft_expr *expr,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_ng_random *priv = nft_expr_priv(expr);
struct rnd_state *state = this_cpu_ptr(&nft_numgen_prandom_state);
u32 val;

val = reciprocal_scale(prandom_u32_state(state), priv->modulus);
regs->data[priv->dreg] = val + priv->offset;
regs->data[priv->dreg] = nft_ng_random_gen(priv);
}

static void nft_ng_random_map_eval(const struct nft_expr *expr,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_ng_random *priv = nft_expr_priv(expr);
const struct nft_set *map = priv->map;
const struct nft_set_ext *ext;
u32 result;
bool found;

result = nft_ng_random_gen(priv);
found = map->ops->lookup(nft_net(pkt), map, &result, &ext);
if (!found)
return;

nft_data_copy(&regs->data[priv->dreg],
nft_set_ext_data(ext), map->dlen);
}

static int nft_ng_random_init(const struct nft_ctx *ctx,
Expand All @@ -204,6 +229,23 @@ static int nft_ng_random_init(const struct nft_ctx *ctx,
NFT_DATA_VALUE, sizeof(u32));
}

static int nft_ng_random_map_init(const struct nft_ctx *ctx,
const struct nft_expr *expr,
const struct nlattr * const tb[])
{
struct nft_ng_random *priv = nft_expr_priv(expr);
u8 genmask = nft_genmask_next(ctx->net);

nft_ng_random_init(ctx, expr, tb);
priv->map = nft_set_lookup_global(ctx->net, ctx->table,
tb[NFTA_NG_SET_NAME],
tb[NFTA_NG_SET_ID], genmask);
if (IS_ERR(priv->map))
return PTR_ERR(priv->map);

return 0;
}

static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
const struct nft_ng_random *priv = nft_expr_priv(expr);
Expand All @@ -212,6 +254,22 @@ static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr)
priv->offset);
}

static int nft_ng_random_map_dump(struct sk_buff *skb,
const struct nft_expr *expr)
{
const struct nft_ng_random *priv = nft_expr_priv(expr);

if (nft_ng_dump(skb, priv->dreg, priv->modulus,
NFT_NG_RANDOM, priv->offset) ||
nla_put_string(skb, NFTA_NG_SET_NAME, priv->map->name))
goto nla_put_failure;

return 0;

nla_put_failure:
return -1;
}

static struct nft_expr_type nft_ng_type;
static const struct nft_expr_ops nft_ng_inc_ops = {
.type = &nft_ng_type,
Expand All @@ -237,6 +295,14 @@ static const struct nft_expr_ops nft_ng_random_ops = {
.dump = nft_ng_random_dump,
};

static const struct nft_expr_ops nft_ng_random_map_ops = {
.type = &nft_ng_type,
.size = NFT_EXPR_SIZE(sizeof(struct nft_ng_random)),
.eval = nft_ng_random_map_eval,
.init = nft_ng_random_map_init,
.dump = nft_ng_random_map_dump,
};

static const struct nft_expr_ops *
nft_ng_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
{
Expand All @@ -255,6 +321,8 @@ nft_ng_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
return &nft_ng_inc_map_ops;
return &nft_ng_inc_ops;
case NFT_NG_RANDOM:
if (tb[NFTA_NG_SET_NAME])
return &nft_ng_random_map_ops;
return &nft_ng_random_ops;
}

Expand Down

0 comments on commit 978d8f9

Please sign in to comment.