@@ -166,18 +166,43 @@ struct nft_ng_random {
166
166
enum nft_registers dreg :8 ;
167
167
u32 modulus ;
168
168
u32 offset ;
169
+ struct nft_set * map ;
169
170
};
170
171
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
+
171
180
static void nft_ng_random_eval (const struct nft_expr * expr ,
172
181
struct nft_regs * regs ,
173
182
const struct nft_pktinfo * pkt )
174
183
{
175
184
struct nft_ng_random * priv = nft_expr_priv (expr );
176
- struct rnd_state * state = this_cpu_ptr (& nft_numgen_prandom_state );
177
- u32 val ;
178
185
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 );
181
206
}
182
207
183
208
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,
204
229
NFT_DATA_VALUE , sizeof (u32 ));
205
230
}
206
231
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
+
207
249
static int nft_ng_random_dump (struct sk_buff * skb , const struct nft_expr * expr )
208
250
{
209
251
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)
212
254
priv -> offset );
213
255
}
214
256
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
+
215
273
static struct nft_expr_type nft_ng_type ;
216
274
static const struct nft_expr_ops nft_ng_inc_ops = {
217
275
.type = & nft_ng_type ,
@@ -237,6 +295,14 @@ static const struct nft_expr_ops nft_ng_random_ops = {
237
295
.dump = nft_ng_random_dump ,
238
296
};
239
297
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
+
240
306
static const struct nft_expr_ops *
241
307
nft_ng_select_ops (const struct nft_ctx * ctx , const struct nlattr * const tb [])
242
308
{
@@ -255,6 +321,8 @@ nft_ng_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
255
321
return & nft_ng_inc_map_ops ;
256
322
return & nft_ng_inc_ops ;
257
323
case NFT_NG_RANDOM :
324
+ if (tb [NFTA_NG_SET_NAME ])
325
+ return & nft_ng_random_map_ops ;
258
326
return & nft_ng_random_ops ;
259
327
}
260
328
0 commit comments