OSDN Git Service

netfilter: nf_tables: prefer direct calls for set lookups
authorFlorian Westphal <fw@strlen.de>
Thu, 13 May 2021 20:29:56 +0000 (22:29 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 28 May 2021 23:04:27 +0000 (01:04 +0200)
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>
include/net/netfilter/nf_tables_core.h
net/netfilter/nft_lookup.c
net/netfilter/nft_set_bitmap.c
net/netfilter/nft_set_hash.c
net/netfilter/nft_set_pipapo.h
net/netfilter/nft_set_pipapo_avx2.h
net/netfilter/nft_set_rbtree.c

index 5eb6994..46c8d5b 100644 (file)
@@ -3,6 +3,7 @@
 #define _NET_NF_TABLES_CORE_H
 
 #include <net/netfilter/nf_tables.h>
+#include <linux/indirect_call_wrapper.h>
 
 extern struct nft_expr_type nft_imm_type;
 extern struct nft_expr_type nft_cmp_type;
@@ -88,12 +89,35 @@ extern const struct nft_set_type nft_set_bitmap_type;
 extern const struct nft_set_type nft_set_pipapo_type;
 extern const struct nft_set_type nft_set_pipapo_avx2_type;
 
+#ifdef CONFIG_RETPOLINE
+bool nft_rhash_lookup(const struct net *net, const struct nft_set *set,
+                     const u32 *key, const struct nft_set_ext **ext);
+bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set,
+                      const u32 *key, const struct nft_set_ext **ext);
+bool nft_bitmap_lookup(const struct net *net, const struct nft_set *set,
+                      const u32 *key, const struct nft_set_ext **ext);
+bool nft_hash_lookup_fast(const struct net *net,
+                         const struct nft_set *set,
+                         const u32 *key, const struct nft_set_ext **ext);
+bool nft_hash_lookup(const struct net *net, const struct nft_set *set,
+                    const u32 *key, const struct nft_set_ext **ext);
+bool nft_set_do_lookup(const struct net *net, const struct nft_set *set,
+                      const u32 *key, const struct nft_set_ext **ext);
+#else
 static inline bool
 nft_set_do_lookup(const struct net *net, const struct nft_set *set,
                  const u32 *key, const struct nft_set_ext **ext)
 {
        return set->ops->lookup(net, set, key, ext);
 }
+#endif
+
+/* called from nft_pipapo_avx2.c */
+bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
+                      const u32 *key, const struct nft_set_ext **ext);
+/* called from nft_set_pipapo.c */
+bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set,
+                           const u32 *key, const struct nft_set_ext **ext);
 
 struct nft_expr;
 struct nft_regs;
index 1a85818..90becbf 100644 (file)
@@ -23,6 +23,37 @@ struct nft_lookup {
        struct nft_set_binding          binding;
 };
 
+#ifdef CONFIG_RETPOLINE
+bool nft_set_do_lookup(const struct net *net, const struct nft_set *set,
+                      const u32 *key, const struct nft_set_ext **ext)
+{
+       if (set->ops == &nft_set_hash_fast_type.ops)
+               return nft_hash_lookup_fast(net, set, key, ext);
+       if (set->ops == &nft_set_hash_type.ops)
+               return nft_hash_lookup(net, set, key, ext);
+
+       if (set->ops == &nft_set_rhash_type.ops)
+               return nft_rhash_lookup(net, set, key, ext);
+
+       if (set->ops == &nft_set_bitmap_type.ops)
+               return nft_bitmap_lookup(net, set, key, ext);
+
+       if (set->ops == &nft_set_pipapo_type.ops)
+               return nft_pipapo_lookup(net, set, key, ext);
+#if defined(CONFIG_X86_64) && !defined(CONFIG_UML)
+       if (set->ops == &nft_set_pipapo_avx2_type.ops)
+               return nft_pipapo_avx2_lookup(net, set, key, ext);
+#endif
+
+       if (set->ops == &nft_set_rbtree_type.ops)
+               return nft_rbtree_lookup(net, set, key, ext);
+
+       WARN_ON_ONCE(1);
+       return set->ops->lookup(net, set, key, ext);
+}
+EXPORT_SYMBOL_GPL(nft_set_do_lookup);
+#endif
+
 void nft_lookup_eval(const struct nft_expr *expr,
                     struct nft_regs *regs,
                     const struct nft_pktinfo *pkt)
index 2a81ea4..e7ae591 100644 (file)
@@ -73,8 +73,9 @@ nft_bitmap_active(const u8 *bitmap, u32 idx, u32 off, u8 genmask)
        return (bitmap[idx] & (0x3 << off)) & (genmask << off);
 }
 
-static bool nft_bitmap_lookup(const struct net *net, const struct nft_set *set,
-                             const u32 *key, const struct nft_set_ext **ext)
+INDIRECT_CALLABLE_SCOPE
+bool nft_bitmap_lookup(const struct net *net, const struct nft_set *set,
+                      const u32 *key, const struct nft_set_ext **ext)
 {
        const struct nft_bitmap *priv = nft_set_priv(set);
        u8 genmask = nft_genmask_cur(net);
index 7b3d0a7..df40314 100644 (file)
@@ -74,8 +74,9 @@ static const struct rhashtable_params nft_rhash_params = {
        .automatic_shrinking    = true,
 };
 
-static bool nft_rhash_lookup(const struct net *net, const struct nft_set *set,
-                            const u32 *key, const struct nft_set_ext **ext)
+INDIRECT_CALLABLE_SCOPE
+bool nft_rhash_lookup(const struct net *net, const struct nft_set *set,
+                     const u32 *key, const struct nft_set_ext **ext)
 {
        struct nft_rhash *priv = nft_set_priv(set);
        const struct nft_rhash_elem *he;
@@ -446,8 +447,9 @@ struct nft_hash_elem {
        struct nft_set_ext              ext;
 };
 
-static bool nft_hash_lookup(const struct net *net, const struct nft_set *set,
-                           const u32 *key, const struct nft_set_ext **ext)
+INDIRECT_CALLABLE_SCOPE
+bool nft_hash_lookup(const struct net *net, const struct nft_set *set,
+                    const u32 *key, const struct nft_set_ext **ext)
 {
        struct nft_hash *priv = nft_set_priv(set);
        u8 genmask = nft_genmask_cur(net);
@@ -484,9 +486,10 @@ static void *nft_hash_get(const struct net *net, const struct nft_set *set,
        return ERR_PTR(-ENOENT);
 }
 
-static bool nft_hash_lookup_fast(const struct net *net,
-                                const struct nft_set *set,
-                                const u32 *key, const struct nft_set_ext **ext)
+INDIRECT_CALLABLE_SCOPE
+bool nft_hash_lookup_fast(const struct net *net,
+                         const struct nft_set *set,
+                         const u32 *key, const struct nft_set_ext **ext)
 {
        struct nft_hash *priv = nft_set_priv(set);
        u8 genmask = nft_genmask_cur(net);
index d84afb8..25a7559 100644 (file)
@@ -178,8 +178,6 @@ struct nft_pipapo_elem {
 
 int pipapo_refill(unsigned long *map, int len, int rules, unsigned long *dst,
                  union nft_pipapo_map_bucket *mt, bool match_only);
-bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
-                      const u32 *key, const struct nft_set_ext **ext);
 
 /**
  * pipapo_and_field_buckets_4bit() - Intersect 4-bit buckets
index 394bcb7..dbb6aac 100644 (file)
@@ -5,8 +5,6 @@
 #include <asm/fpu/xstate.h>
 #define NFT_PIPAPO_ALIGN       (XSAVE_YMM_SIZE / BITS_PER_BYTE)
 
-bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set,
-                           const u32 *key, const struct nft_set_ext **ext);
 bool nft_pipapo_avx2_estimate(const struct nft_set_desc *desc, u32 features,
                              struct nft_set_estimate *est);
 #endif /* defined(CONFIG_X86_64) && !defined(CONFIG_UML) */
index 9e36eb4..d600a56 100644 (file)
@@ -107,8 +107,9 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set
        return false;
 }
 
-static bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set,
-                             const u32 *key, const struct nft_set_ext **ext)
+INDIRECT_CALLABLE_SCOPE
+bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set,
+                      const u32 *key, const struct nft_set_ext **ext)
 {
        struct nft_rbtree *priv = nft_set_priv(set);
        unsigned int seq = read_seqcount_begin(&priv->count);