@@ -25,6 +25,7 @@ struct nft_jhash {
25
25
u32 modulus ;
26
26
u32 seed ;
27
27
u32 offset ;
28
+ struct nft_set * map ;
28
29
};
29
30
30
31
static void nft_jhash_eval (const struct nft_expr * expr ,
@@ -35,14 +36,39 @@ static void nft_jhash_eval(const struct nft_expr *expr,
35
36
const void * data = & regs -> data [priv -> sreg ];
36
37
u32 h ;
37
38
38
- h = reciprocal_scale (jhash (data , priv -> len , priv -> seed ), priv -> modulus );
39
+ h = reciprocal_scale (jhash (data , priv -> len , priv -> seed ),
40
+ priv -> modulus );
41
+
39
42
regs -> data [priv -> dreg ] = h + priv -> offset ;
40
43
}
41
44
45
+ static void nft_jhash_map_eval (const struct nft_expr * expr ,
46
+ struct nft_regs * regs ,
47
+ const struct nft_pktinfo * pkt )
48
+ {
49
+ struct nft_jhash * priv = nft_expr_priv (expr );
50
+ const void * data = & regs -> data [priv -> sreg ];
51
+ const struct nft_set * map = priv -> map ;
52
+ const struct nft_set_ext * ext ;
53
+ u32 result ;
54
+ bool found ;
55
+
56
+ result = reciprocal_scale (jhash (data , priv -> len , priv -> seed ),
57
+ priv -> modulus ) + priv -> offset ;
58
+
59
+ found = map -> ops -> lookup (nft_net (pkt ), map , & result , & ext );
60
+ if (!found )
61
+ return ;
62
+
63
+ nft_data_copy (& regs -> data [priv -> dreg ],
64
+ nft_set_ext_data (ext ), map -> dlen );
65
+ }
66
+
42
67
struct nft_symhash {
43
68
enum nft_registers dreg :8 ;
44
69
u32 modulus ;
45
70
u32 offset ;
71
+ struct nft_set * map ;
46
72
};
47
73
48
74
static void nft_symhash_eval (const struct nft_expr * expr ,
@@ -58,6 +84,28 @@ static void nft_symhash_eval(const struct nft_expr *expr,
58
84
regs -> data [priv -> dreg ] = h + priv -> offset ;
59
85
}
60
86
87
+ static void nft_symhash_map_eval (const struct nft_expr * expr ,
88
+ struct nft_regs * regs ,
89
+ const struct nft_pktinfo * pkt )
90
+ {
91
+ struct nft_symhash * priv = nft_expr_priv (expr );
92
+ struct sk_buff * skb = pkt -> skb ;
93
+ const struct nft_set * map = priv -> map ;
94
+ const struct nft_set_ext * ext ;
95
+ u32 result ;
96
+ bool found ;
97
+
98
+ result = reciprocal_scale (__skb_get_hash_symmetric (skb ),
99
+ priv -> modulus ) + priv -> offset ;
100
+
101
+ found = map -> ops -> lookup (nft_net (pkt ), map , & result , & ext );
102
+ if (!found )
103
+ return ;
104
+
105
+ nft_data_copy (& regs -> data [priv -> dreg ],
106
+ nft_set_ext_data (ext ), map -> dlen );
107
+ }
108
+
61
109
static const struct nla_policy nft_hash_policy [NFTA_HASH_MAX + 1 ] = {
62
110
[NFTA_HASH_SREG ] = { .type = NLA_U32 },
63
111
[NFTA_HASH_DREG ] = { .type = NLA_U32 },
@@ -66,6 +114,9 @@ static const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
66
114
[NFTA_HASH_SEED ] = { .type = NLA_U32 },
67
115
[NFTA_HASH_OFFSET ] = { .type = NLA_U32 },
68
116
[NFTA_HASH_TYPE ] = { .type = NLA_U32 },
117
+ [NFTA_HASH_SET_NAME ] = { .type = NLA_STRING ,
118
+ .len = NFT_SET_MAXNAMELEN - 1 },
119
+ [NFTA_HASH_SET_ID ] = { .type = NLA_U32 },
69
120
};
70
121
71
122
static int nft_jhash_init (const struct nft_ctx * ctx ,
@@ -115,6 +166,23 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
115
166
NFT_DATA_VALUE , sizeof (u32 ));
116
167
}
117
168
169
+ static int nft_jhash_map_init (const struct nft_ctx * ctx ,
170
+ const struct nft_expr * expr ,
171
+ const struct nlattr * const tb [])
172
+ {
173
+ struct nft_jhash * priv = nft_expr_priv (expr );
174
+ u8 genmask = nft_genmask_next (ctx -> net );
175
+
176
+ nft_jhash_init (ctx , expr , tb );
177
+ priv -> map = nft_set_lookup_global (ctx -> net , ctx -> table ,
178
+ tb [NFTA_HASH_SET_NAME ],
179
+ tb [NFTA_HASH_SET_ID ], genmask );
180
+ if (IS_ERR (priv -> map ))
181
+ return PTR_ERR (priv -> map );
182
+
183
+ return 0 ;
184
+ }
185
+
118
186
static int nft_symhash_init (const struct nft_ctx * ctx ,
119
187
const struct nft_expr * expr ,
120
188
const struct nlattr * const tb [])
@@ -141,6 +209,23 @@ static int nft_symhash_init(const struct nft_ctx *ctx,
141
209
NFT_DATA_VALUE , sizeof (u32 ));
142
210
}
143
211
212
+ static int nft_symhash_map_init (const struct nft_ctx * ctx ,
213
+ const struct nft_expr * expr ,
214
+ const struct nlattr * const tb [])
215
+ {
216
+ struct nft_jhash * priv = nft_expr_priv (expr );
217
+ u8 genmask = nft_genmask_next (ctx -> net );
218
+
219
+ nft_symhash_init (ctx , expr , tb );
220
+ priv -> map = nft_set_lookup_global (ctx -> net , ctx -> table ,
221
+ tb [NFTA_HASH_SET_NAME ],
222
+ tb [NFTA_HASH_SET_ID ], genmask );
223
+ if (IS_ERR (priv -> map ))
224
+ return PTR_ERR (priv -> map );
225
+
226
+ return 0 ;
227
+ }
228
+
144
229
static int nft_jhash_dump (struct sk_buff * skb ,
145
230
const struct nft_expr * expr )
146
231
{
@@ -168,6 +253,18 @@ static int nft_jhash_dump(struct sk_buff *skb,
168
253
return -1 ;
169
254
}
170
255
256
+ static int nft_jhash_map_dump (struct sk_buff * skb ,
257
+ const struct nft_expr * expr )
258
+ {
259
+ const struct nft_jhash * priv = nft_expr_priv (expr );
260
+
261
+ if (nft_jhash_dump (skb , expr ) ||
262
+ nla_put_string (skb , NFTA_HASH_SET_NAME , priv -> map -> name ))
263
+ return -1 ;
264
+
265
+ return 0 ;
266
+ }
267
+
171
268
static int nft_symhash_dump (struct sk_buff * skb ,
172
269
const struct nft_expr * expr )
173
270
{
@@ -188,6 +285,18 @@ static int nft_symhash_dump(struct sk_buff *skb,
188
285
return -1 ;
189
286
}
190
287
288
+ static int nft_symhash_map_dump (struct sk_buff * skb ,
289
+ const struct nft_expr * expr )
290
+ {
291
+ const struct nft_symhash * priv = nft_expr_priv (expr );
292
+
293
+ if (nft_symhash_dump (skb , expr ) ||
294
+ nla_put_string (skb , NFTA_HASH_SET_NAME , priv -> map -> name ))
295
+ return -1 ;
296
+
297
+ return 0 ;
298
+ }
299
+
191
300
static struct nft_expr_type nft_hash_type ;
192
301
static const struct nft_expr_ops nft_jhash_ops = {
193
302
.type = & nft_hash_type ,
@@ -197,6 +306,14 @@ static const struct nft_expr_ops nft_jhash_ops = {
197
306
.dump = nft_jhash_dump ,
198
307
};
199
308
309
+ static const struct nft_expr_ops nft_jhash_map_ops = {
310
+ .type = & nft_hash_type ,
311
+ .size = NFT_EXPR_SIZE (sizeof (struct nft_jhash )),
312
+ .eval = nft_jhash_map_eval ,
313
+ .init = nft_jhash_map_init ,
314
+ .dump = nft_jhash_map_dump ,
315
+ };
316
+
200
317
static const struct nft_expr_ops nft_symhash_ops = {
201
318
.type = & nft_hash_type ,
202
319
.size = NFT_EXPR_SIZE (sizeof (struct nft_symhash )),
@@ -205,6 +322,14 @@ static const struct nft_expr_ops nft_symhash_ops = {
205
322
.dump = nft_symhash_dump ,
206
323
};
207
324
325
+ static const struct nft_expr_ops nft_symhash_map_ops = {
326
+ .type = & nft_hash_type ,
327
+ .size = NFT_EXPR_SIZE (sizeof (struct nft_symhash )),
328
+ .eval = nft_symhash_map_eval ,
329
+ .init = nft_symhash_map_init ,
330
+ .dump = nft_symhash_map_dump ,
331
+ };
332
+
208
333
static const struct nft_expr_ops *
209
334
nft_hash_select_ops (const struct nft_ctx * ctx ,
210
335
const struct nlattr * const tb [])
@@ -217,8 +342,12 @@ nft_hash_select_ops(const struct nft_ctx *ctx,
217
342
type = ntohl (nla_get_be32 (tb [NFTA_HASH_TYPE ]));
218
343
switch (type ) {
219
344
case NFT_HASH_SYM :
345
+ if (tb [NFTA_HASH_SET_NAME ])
346
+ return & nft_symhash_map_ops ;
220
347
return & nft_symhash_ops ;
221
348
case NFT_HASH_JENKINS :
349
+ if (tb [NFTA_HASH_SET_NAME ])
350
+ return & nft_jhash_map_ops ;
222
351
return & nft_jhash_ops ;
223
352
default :
224
353
break ;
0 commit comments