Skip to content

Commit 06f714d

Browse files
Florian Westphalgregkh
authored andcommitted
netfilter: nft_set: remove one argument from lookup and update functions
[ Upstream commit 17a20e0 ] Return the extension pointer instead of passing it as a function argument to be filled in by the callee. As-is, whenever false is returned, the extension pointer is not used. For all set types, when true is returned, the extension pointer was set to the matching element. Only exception: nft_set_bitmap doesn't support extensions. Return a pointer to a static const empty element extension container. return false -> return NULL return true -> return the elements' extension pointer. This saves one function argument. Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Stable-dep-of: c4eaca2 ("netfilter: nft_set_pipapo: don't check genbit from packetpath lookups") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 52f951a commit 06f714d

10 files changed

Lines changed: 126 additions & 117 deletions

File tree

include/net/netfilter/nf_tables.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -459,19 +459,17 @@ struct nft_set_ext;
459459
* control plane functions.
460460
*/
461461
struct nft_set_ops {
462-
bool (*lookup)(const struct net *net,
462+
const struct nft_set_ext * (*lookup)(const struct net *net,
463463
const struct nft_set *set,
464-
const u32 *key,
465-
const struct nft_set_ext **ext);
466-
bool (*update)(struct nft_set *set,
464+
const u32 *key);
465+
const struct nft_set_ext * (*update)(struct nft_set *set,
467466
const u32 *key,
468467
struct nft_elem_priv *
469468
(*new)(struct nft_set *,
470469
const struct nft_expr *,
471470
struct nft_regs *),
472471
const struct nft_expr *expr,
473-
struct nft_regs *regs,
474-
const struct nft_set_ext **ext);
472+
struct nft_regs *regs);
475473
bool (*delete)(const struct nft_set *set,
476474
const u32 *key);
477475

include/net/netfilter/nf_tables_core.h

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -94,34 +94,41 @@ extern const struct nft_set_type nft_set_pipapo_type;
9494
extern const struct nft_set_type nft_set_pipapo_avx2_type;
9595

9696
#ifdef CONFIG_MITIGATION_RETPOLINE
97-
bool nft_rhash_lookup(const struct net *net, const struct nft_set *set,
98-
const u32 *key, const struct nft_set_ext **ext);
99-
bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set,
100-
const u32 *key, const struct nft_set_ext **ext);
101-
bool nft_bitmap_lookup(const struct net *net, const struct nft_set *set,
102-
const u32 *key, const struct nft_set_ext **ext);
103-
bool nft_hash_lookup_fast(const struct net *net,
104-
const struct nft_set *set,
105-
const u32 *key, const struct nft_set_ext **ext);
106-
bool nft_hash_lookup(const struct net *net, const struct nft_set *set,
107-
const u32 *key, const struct nft_set_ext **ext);
108-
bool nft_set_do_lookup(const struct net *net, const struct nft_set *set,
109-
const u32 *key, const struct nft_set_ext **ext);
97+
const struct nft_set_ext *
98+
nft_rhash_lookup(const struct net *net, const struct nft_set *set,
99+
const u32 *key);
100+
const struct nft_set_ext *
101+
nft_rbtree_lookup(const struct net *net, const struct nft_set *set,
102+
const u32 *key);
103+
const struct nft_set_ext *
104+
nft_bitmap_lookup(const struct net *net, const struct nft_set *set,
105+
const u32 *key);
106+
const struct nft_set_ext *
107+
nft_hash_lookup_fast(const struct net *net, const struct nft_set *set,
108+
const u32 *key);
109+
const struct nft_set_ext *
110+
nft_hash_lookup(const struct net *net, const struct nft_set *set,
111+
const u32 *key);
112+
const struct nft_set_ext *
113+
nft_set_do_lookup(const struct net *net, const struct nft_set *set,
114+
const u32 *key);
110115
#else
111-
static inline bool
116+
static inline const struct nft_set_ext *
112117
nft_set_do_lookup(const struct net *net, const struct nft_set *set,
113-
const u32 *key, const struct nft_set_ext **ext)
118+
const u32 *key)
114119
{
115-
return set->ops->lookup(net, set, key, ext);
120+
return set->ops->lookup(net, set, key);
116121
}
117122
#endif
118123

119124
/* called from nft_pipapo_avx2.c */
120-
bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
121-
const u32 *key, const struct nft_set_ext **ext);
125+
const struct nft_set_ext *
126+
nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
127+
const u32 *key);
122128
/* called from nft_set_pipapo.c */
123-
bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set,
124-
const u32 *key, const struct nft_set_ext **ext);
129+
const struct nft_set_ext *
130+
nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set,
131+
const u32 *key);
125132

126133
void nft_counter_init_seqcount(void);
127134

net/netfilter/nft_dynset.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,9 @@ void nft_dynset_eval(const struct nft_expr *expr,
9191
return;
9292
}
9393

94-
if (set->ops->update(set, &regs->data[priv->sreg_key], nft_dynset_new,
95-
expr, regs, &ext)) {
94+
ext = set->ops->update(set, &regs->data[priv->sreg_key], nft_dynset_new,
95+
expr, regs);
96+
if (ext) {
9697
if (priv->op == NFT_DYNSET_OP_UPDATE &&
9798
nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
9899
READ_ONCE(nft_set_ext_timeout(ext)->timeout) != 0) {

net/netfilter/nft_lookup.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,33 @@ struct nft_lookup {
2525
};
2626

2727
#ifdef CONFIG_MITIGATION_RETPOLINE
28-
bool nft_set_do_lookup(const struct net *net, const struct nft_set *set,
29-
const u32 *key, const struct nft_set_ext **ext)
28+
const struct nft_set_ext *
29+
nft_set_do_lookup(const struct net *net, const struct nft_set *set,
30+
const u32 *key)
3031
{
3132
if (set->ops == &nft_set_hash_fast_type.ops)
32-
return nft_hash_lookup_fast(net, set, key, ext);
33+
return nft_hash_lookup_fast(net, set, key);
3334
if (set->ops == &nft_set_hash_type.ops)
34-
return nft_hash_lookup(net, set, key, ext);
35+
return nft_hash_lookup(net, set, key);
3536

3637
if (set->ops == &nft_set_rhash_type.ops)
37-
return nft_rhash_lookup(net, set, key, ext);
38+
return nft_rhash_lookup(net, set, key);
3839

3940
if (set->ops == &nft_set_bitmap_type.ops)
40-
return nft_bitmap_lookup(net, set, key, ext);
41+
return nft_bitmap_lookup(net, set, key);
4142

4243
if (set->ops == &nft_set_pipapo_type.ops)
43-
return nft_pipapo_lookup(net, set, key, ext);
44+
return nft_pipapo_lookup(net, set, key);
4445
#if defined(CONFIG_X86_64) && !defined(CONFIG_UML)
4546
if (set->ops == &nft_set_pipapo_avx2_type.ops)
46-
return nft_pipapo_avx2_lookup(net, set, key, ext);
47+
return nft_pipapo_avx2_lookup(net, set, key);
4748
#endif
4849

4950
if (set->ops == &nft_set_rbtree_type.ops)
50-
return nft_rbtree_lookup(net, set, key, ext);
51+
return nft_rbtree_lookup(net, set, key);
5152

5253
WARN_ON_ONCE(1);
53-
return set->ops->lookup(net, set, key, ext);
54+
return set->ops->lookup(net, set, key);
5455
}
5556
EXPORT_SYMBOL_GPL(nft_set_do_lookup);
5657
#endif
@@ -61,12 +62,12 @@ void nft_lookup_eval(const struct nft_expr *expr,
6162
{
6263
const struct nft_lookup *priv = nft_expr_priv(expr);
6364
const struct nft_set *set = priv->set;
64-
const struct nft_set_ext *ext = NULL;
6565
const struct net *net = nft_net(pkt);
66+
const struct nft_set_ext *ext;
6667
bool found;
6768

68-
found = nft_set_do_lookup(net, set, &regs->data[priv->sreg], &ext) ^
69-
priv->invert;
69+
ext = nft_set_do_lookup(net, set, &regs->data[priv->sreg]);
70+
found = !!ext ^ priv->invert;
7071
if (!found) {
7172
ext = nft_set_catchall_lookup(net, set);
7273
if (!ext) {

net/netfilter/nft_objref.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,9 @@ void nft_objref_map_eval(const struct nft_expr *expr,
111111
struct net *net = nft_net(pkt);
112112
const struct nft_set_ext *ext;
113113
struct nft_object *obj;
114-
bool found;
115114

116-
found = nft_set_do_lookup(net, set, &regs->data[priv->sreg], &ext);
117-
if (!found) {
115+
ext = nft_set_do_lookup(net, set, &regs->data[priv->sreg]);
116+
if (!ext) {
118117
ext = nft_set_catchall_lookup(net, set);
119118
if (!ext) {
120119
regs->verdict.code = NFT_BREAK;

net/netfilter/nft_set_bitmap.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,21 @@ nft_bitmap_active(const u8 *bitmap, u32 idx, u32 off, u8 genmask)
7575
}
7676

7777
INDIRECT_CALLABLE_SCOPE
78-
bool nft_bitmap_lookup(const struct net *net, const struct nft_set *set,
79-
const u32 *key, const struct nft_set_ext **ext)
78+
const struct nft_set_ext *
79+
nft_bitmap_lookup(const struct net *net, const struct nft_set *set,
80+
const u32 *key)
8081
{
8182
const struct nft_bitmap *priv = nft_set_priv(set);
83+
static const struct nft_set_ext found;
8284
u8 genmask = nft_genmask_cur(net);
8385
u32 idx, off;
8486

8587
nft_bitmap_location(set, key, &idx, &off);
8688

87-
return nft_bitmap_active(priv->bitmap, idx, off, genmask);
89+
if (nft_bitmap_active(priv->bitmap, idx, off, genmask))
90+
return &found;
91+
92+
return NULL;
8893
}
8994

9095
static struct nft_bitmap_elem *

net/netfilter/nft_set_hash.c

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,9 @@ static const struct rhashtable_params nft_rhash_params = {
8181
};
8282

8383
INDIRECT_CALLABLE_SCOPE
84-
bool nft_rhash_lookup(const struct net *net, const struct nft_set *set,
85-
const u32 *key, const struct nft_set_ext **ext)
84+
const struct nft_set_ext *
85+
nft_rhash_lookup(const struct net *net, const struct nft_set *set,
86+
const u32 *key)
8687
{
8788
struct nft_rhash *priv = nft_set_priv(set);
8889
const struct nft_rhash_elem *he;
@@ -95,9 +96,9 @@ bool nft_rhash_lookup(const struct net *net, const struct nft_set *set,
9596

9697
he = rhashtable_lookup(&priv->ht, &arg, nft_rhash_params);
9798
if (he != NULL)
98-
*ext = &he->ext;
99+
return &he->ext;
99100

100-
return !!he;
101+
return NULL;
101102
}
102103

103104
static struct nft_elem_priv *
@@ -120,14 +121,11 @@ nft_rhash_get(const struct net *net, const struct nft_set *set,
120121
return ERR_PTR(-ENOENT);
121122
}
122123

123-
static bool nft_rhash_update(struct nft_set *set, const u32 *key,
124-
struct nft_elem_priv *
125-
(*new)(struct nft_set *,
126-
const struct nft_expr *,
127-
struct nft_regs *regs),
128-
const struct nft_expr *expr,
129-
struct nft_regs *regs,
130-
const struct nft_set_ext **ext)
124+
static const struct nft_set_ext *
125+
nft_rhash_update(struct nft_set *set, const u32 *key,
126+
struct nft_elem_priv *(*new)(struct nft_set *, const struct nft_expr *,
127+
struct nft_regs *regs),
128+
const struct nft_expr *expr, struct nft_regs *regs)
131129
{
132130
struct nft_rhash *priv = nft_set_priv(set);
133131
struct nft_rhash_elem *he, *prev;
@@ -161,14 +159,13 @@ static bool nft_rhash_update(struct nft_set *set, const u32 *key,
161159
}
162160

163161
out:
164-
*ext = &he->ext;
165-
return true;
162+
return &he->ext;
166163

167164
err2:
168165
nft_set_elem_destroy(set, &he->priv, true);
169166
atomic_dec(&set->nelems);
170167
err1:
171-
return false;
168+
return NULL;
172169
}
173170

174171
static int nft_rhash_insert(const struct net *net, const struct nft_set *set,
@@ -507,8 +504,9 @@ struct nft_hash_elem {
507504
};
508505

509506
INDIRECT_CALLABLE_SCOPE
510-
bool nft_hash_lookup(const struct net *net, const struct nft_set *set,
511-
const u32 *key, const struct nft_set_ext **ext)
507+
const struct nft_set_ext *
508+
nft_hash_lookup(const struct net *net, const struct nft_set *set,
509+
const u32 *key)
512510
{
513511
struct nft_hash *priv = nft_set_priv(set);
514512
u8 genmask = nft_genmask_cur(net);
@@ -519,12 +517,10 @@ bool nft_hash_lookup(const struct net *net, const struct nft_set *set,
519517
hash = reciprocal_scale(hash, priv->buckets);
520518
hlist_for_each_entry_rcu(he, &priv->table[hash], node) {
521519
if (!memcmp(nft_set_ext_key(&he->ext), key, set->klen) &&
522-
nft_set_elem_active(&he->ext, genmask)) {
523-
*ext = &he->ext;
524-
return true;
525-
}
520+
nft_set_elem_active(&he->ext, genmask))
521+
return &he->ext;
526522
}
527-
return false;
523+
return NULL;
528524
}
529525

530526
static struct nft_elem_priv *
@@ -547,9 +543,9 @@ nft_hash_get(const struct net *net, const struct nft_set *set,
547543
}
548544

549545
INDIRECT_CALLABLE_SCOPE
550-
bool nft_hash_lookup_fast(const struct net *net,
551-
const struct nft_set *set,
552-
const u32 *key, const struct nft_set_ext **ext)
546+
const struct nft_set_ext *
547+
nft_hash_lookup_fast(const struct net *net, const struct nft_set *set,
548+
const u32 *key)
553549
{
554550
struct nft_hash *priv = nft_set_priv(set);
555551
u8 genmask = nft_genmask_cur(net);
@@ -562,12 +558,10 @@ bool nft_hash_lookup_fast(const struct net *net,
562558
hlist_for_each_entry_rcu(he, &priv->table[hash], node) {
563559
k2 = *(u32 *)nft_set_ext_key(&he->ext)->data;
564560
if (k1 == k2 &&
565-
nft_set_elem_active(&he->ext, genmask)) {
566-
*ext = &he->ext;
567-
return true;
568-
}
561+
nft_set_elem_active(&he->ext, genmask))
562+
return &he->ext;
569563
}
570-
return false;
564+
return NULL;
571565
}
572566

573567
static u32 nft_jhash(const struct nft_set *set, const struct nft_hash *priv,

net/netfilter/nft_set_pipapo.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,9 @@ int pipapo_refill(unsigned long *map, unsigned int len, unsigned int rules,
407407
*
408408
* Return: true on match, false otherwise.
409409
*/
410-
bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
411-
const u32 *key, const struct nft_set_ext **ext)
410+
const struct nft_set_ext *
411+
nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
412+
const u32 *key)
412413
{
413414
struct nft_pipapo *priv = nft_set_priv(set);
414415
struct nft_pipapo_scratch *scratch;
@@ -465,13 +466,15 @@ bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
465466
scratch->map_index = map_index;
466467
local_bh_enable();
467468

468-
return false;
469+
return NULL;
469470
}
470471

471472
if (last) {
472-
*ext = &f->mt[b].e->ext;
473-
if (unlikely(nft_set_elem_expired(*ext) ||
474-
!nft_set_elem_active(*ext, genmask)))
473+
const struct nft_set_ext *ext;
474+
475+
ext = &f->mt[b].e->ext;
476+
if (unlikely(nft_set_elem_expired(ext) ||
477+
!nft_set_elem_active(ext, genmask)))
475478
goto next_match;
476479

477480
/* Last field: we're just returning the key without
@@ -482,7 +485,7 @@ bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
482485
scratch->map_index = map_index;
483486
local_bh_enable();
484487

485-
return true;
488+
return ext;
486489
}
487490

488491
/* Swap bitmap indices: res_map is the initial bitmap for the
@@ -497,7 +500,7 @@ bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
497500

498501
out:
499502
local_bh_enable();
500-
return false;
503+
return NULL;
501504
}
502505

503506
/**

0 commit comments

Comments
 (0)