Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nf_tables: prefer direct calls for set lookups

Extend nft_set_do_lookup() to use direct calls when retpoline feature
is enabled.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
f227925e 0974cff3

+71 -15
+24
include/net/netfilter/nf_tables_core.h
··· 3 3 #define _NET_NF_TABLES_CORE_H 4 4 5 5 #include <net/netfilter/nf_tables.h> 6 + #include <linux/indirect_call_wrapper.h> 6 7 7 8 extern struct nft_expr_type nft_imm_type; 8 9 extern struct nft_expr_type nft_cmp_type; ··· 89 88 extern const struct nft_set_type nft_set_pipapo_type; 90 89 extern const struct nft_set_type nft_set_pipapo_avx2_type; 91 90 91 + #ifdef CONFIG_RETPOLINE 92 + bool nft_rhash_lookup(const struct net *net, const struct nft_set *set, 93 + const u32 *key, const struct nft_set_ext **ext); 94 + bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set, 95 + const u32 *key, const struct nft_set_ext **ext); 96 + bool nft_bitmap_lookup(const struct net *net, const struct nft_set *set, 97 + const u32 *key, const struct nft_set_ext **ext); 98 + bool nft_hash_lookup_fast(const struct net *net, 99 + const struct nft_set *set, 100 + const u32 *key, const struct nft_set_ext **ext); 101 + bool nft_hash_lookup(const struct net *net, const struct nft_set *set, 102 + const u32 *key, const struct nft_set_ext **ext); 103 + bool nft_set_do_lookup(const struct net *net, const struct nft_set *set, 104 + const u32 *key, const struct nft_set_ext **ext); 105 + #else 92 106 static inline bool 93 107 nft_set_do_lookup(const struct net *net, const struct nft_set *set, 94 108 const u32 *key, const struct nft_set_ext **ext) 95 109 { 96 110 return set->ops->lookup(net, set, key, ext); 97 111 } 112 + #endif 113 + 114 + /* called from nft_pipapo_avx2.c */ 115 + bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set, 116 + const u32 *key, const struct nft_set_ext **ext); 117 + /* called from nft_set_pipapo.c */ 118 + bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set, 119 + const u32 *key, const struct nft_set_ext **ext); 98 120 99 121 struct nft_expr; 100 122 struct nft_regs;
+31
net/netfilter/nft_lookup.c
··· 23 23 struct nft_set_binding binding; 24 24 }; 25 25 26 + #ifdef CONFIG_RETPOLINE 27 + bool nft_set_do_lookup(const struct net *net, const struct nft_set *set, 28 + const u32 *key, const struct nft_set_ext **ext) 29 + { 30 + if (set->ops == &nft_set_hash_fast_type.ops) 31 + return nft_hash_lookup_fast(net, set, key, ext); 32 + if (set->ops == &nft_set_hash_type.ops) 33 + return nft_hash_lookup(net, set, key, ext); 34 + 35 + if (set->ops == &nft_set_rhash_type.ops) 36 + return nft_rhash_lookup(net, set, key, ext); 37 + 38 + if (set->ops == &nft_set_bitmap_type.ops) 39 + return nft_bitmap_lookup(net, set, key, ext); 40 + 41 + if (set->ops == &nft_set_pipapo_type.ops) 42 + return nft_pipapo_lookup(net, set, key, ext); 43 + #if defined(CONFIG_X86_64) && !defined(CONFIG_UML) 44 + if (set->ops == &nft_set_pipapo_avx2_type.ops) 45 + return nft_pipapo_avx2_lookup(net, set, key, ext); 46 + #endif 47 + 48 + if (set->ops == &nft_set_rbtree_type.ops) 49 + return nft_rbtree_lookup(net, set, key, ext); 50 + 51 + WARN_ON_ONCE(1); 52 + return set->ops->lookup(net, set, key, ext); 53 + } 54 + EXPORT_SYMBOL_GPL(nft_set_do_lookup); 55 + #endif 56 + 26 57 void nft_lookup_eval(const struct nft_expr *expr, 27 58 struct nft_regs *regs, 28 59 const struct nft_pktinfo *pkt)
+3 -2
net/netfilter/nft_set_bitmap.c
··· 73 73 return (bitmap[idx] & (0x3 << off)) & (genmask << off); 74 74 } 75 75 76 - static bool nft_bitmap_lookup(const struct net *net, const struct nft_set *set, 77 - const u32 *key, const struct nft_set_ext **ext) 76 + INDIRECT_CALLABLE_SCOPE 77 + bool nft_bitmap_lookup(const struct net *net, const struct nft_set *set, 78 + const u32 *key, const struct nft_set_ext **ext) 78 79 { 79 80 const struct nft_bitmap *priv = nft_set_priv(set); 80 81 u8 genmask = nft_genmask_cur(net);
+10 -7
net/netfilter/nft_set_hash.c
··· 74 74 .automatic_shrinking = true, 75 75 }; 76 76 77 - static bool nft_rhash_lookup(const struct net *net, const struct nft_set *set, 78 - const u32 *key, const struct nft_set_ext **ext) 77 + INDIRECT_CALLABLE_SCOPE 78 + bool nft_rhash_lookup(const struct net *net, const struct nft_set *set, 79 + const u32 *key, const struct nft_set_ext **ext) 79 80 { 80 81 struct nft_rhash *priv = nft_set_priv(set); 81 82 const struct nft_rhash_elem *he; ··· 447 446 struct nft_set_ext ext; 448 447 }; 449 448 450 - static bool nft_hash_lookup(const struct net *net, const struct nft_set *set, 451 - const u32 *key, const struct nft_set_ext **ext) 449 + INDIRECT_CALLABLE_SCOPE 450 + bool nft_hash_lookup(const struct net *net, const struct nft_set *set, 451 + const u32 *key, const struct nft_set_ext **ext) 452 452 { 453 453 struct nft_hash *priv = nft_set_priv(set); 454 454 u8 genmask = nft_genmask_cur(net); ··· 486 484 return ERR_PTR(-ENOENT); 487 485 } 488 486 489 - static bool nft_hash_lookup_fast(const struct net *net, 490 - const struct nft_set *set, 491 - const u32 *key, const struct nft_set_ext **ext) 487 + INDIRECT_CALLABLE_SCOPE 488 + bool nft_hash_lookup_fast(const struct net *net, 489 + const struct nft_set *set, 490 + const u32 *key, const struct nft_set_ext **ext) 492 491 { 493 492 struct nft_hash *priv = nft_set_priv(set); 494 493 u8 genmask = nft_genmask_cur(net);
-2
net/netfilter/nft_set_pipapo.h
··· 178 178 179 179 int pipapo_refill(unsigned long *map, int len, int rules, unsigned long *dst, 180 180 union nft_pipapo_map_bucket *mt, bool match_only); 181 - bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set, 182 - const u32 *key, const struct nft_set_ext **ext); 183 181 184 182 /** 185 183 * pipapo_and_field_buckets_4bit() - Intersect 4-bit buckets
-2
net/netfilter/nft_set_pipapo_avx2.h
··· 5 5 #include <asm/fpu/xstate.h> 6 6 #define NFT_PIPAPO_ALIGN (XSAVE_YMM_SIZE / BITS_PER_BYTE) 7 7 8 - bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set, 9 - const u32 *key, const struct nft_set_ext **ext); 10 8 bool nft_pipapo_avx2_estimate(const struct nft_set_desc *desc, u32 features, 11 9 struct nft_set_estimate *est); 12 10 #endif /* defined(CONFIG_X86_64) && !defined(CONFIG_UML) */
+3 -2
net/netfilter/nft_set_rbtree.c
··· 107 107 return false; 108 108 } 109 109 110 - static bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set, 111 - const u32 *key, const struct nft_set_ext **ext) 110 + INDIRECT_CALLABLE_SCOPE 111 + bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set, 112 + const u32 *key, const struct nft_set_ext **ext) 112 113 { 113 114 struct nft_rbtree *priv = nft_set_priv(set); 114 115 unsigned int seq = read_seqcount_begin(&priv->count);