]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
netfilter: nf_tables: add space notation to sets
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 18 Jan 2017 17:30:12 +0000 (18:30 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 8 Feb 2017 13:16:21 +0000 (14:16 +0100)
The space notation allows us to classify the set backend implementation
based on the amount of required memory. This provides an order of the
set representation scalability in terms of memory. The size field is
still left in place so use this if the userspace provides no explicit
number of elements, so we cannot calculate the real memory that this set
needs. This also helps us break ties in the set backend selection
routine, eg. two backend implementations provide the same performance.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/netfilter/nf_tables.h
net/netfilter/nf_tables_api.c
net/netfilter/nft_set_hash.c
net/netfilter/nft_set_rbtree.c

index d76ac2f80a40b2244f4e44d214967b896f309902..21ce50e6d0c5f436c1c1daaf38ae5ad34ef846de 100644 (file)
@@ -245,10 +245,12 @@ enum nft_set_class {
  *
  *     @size: required memory
  *     @lookup: lookup performance class
+ *     @space: memory class
  */
 struct nft_set_estimate {
        unsigned int            size;
        enum nft_set_class      lookup;
+       enum nft_set_class      space;
 };
 
 struct nft_set_ext;
index fa7cd16790791c40079e88bb9d9d6d939b378844..cb6ae46f6c48e5c8d013b54ab6a743e117a2c929 100644 (file)
@@ -2404,6 +2404,7 @@ nft_select_set_ops(const struct nlattr * const nla[],
        bops        = NULL;
        best.size   = ~0;
        best.lookup = ~0;
+       best.space  = ~0;
 
        list_for_each_entry(ops, &nf_tables_set_ops, list) {
                if ((ops->features & features) != features)
@@ -2415,14 +2416,25 @@ nft_select_set_ops(const struct nlattr * const nla[],
                case NFT_SET_POL_PERFORMANCE:
                        if (est.lookup < best.lookup)
                                break;
-                       if (est.lookup == best.lookup && est.size < best.size)
-                               break;
+                       if (est.lookup == best.lookup) {
+                               if (!desc->size) {
+                                       if (est.space < best.space)
+                                               break;
+                               } else if (est.size < best.size) {
+                                       break;
+                               }
+                       }
                        continue;
                case NFT_SET_POL_MEMORY:
-                       if (est.size < best.size)
-                               break;
-                       if (est.size == best.size && est.lookup < best.lookup)
+                       if (!desc->size) {
+                               if (est.space < best.space)
+                                       break;
+                               if (est.space == best.space &&
+                                   est.lookup < best.lookup)
+                                       break;
+                       } else if (est.size < best.size) {
                                break;
+                       }
                        continue;
                default:
                        break;
index e58e7f02138bdefe00810626cf5cbf57b2838d3a..6938bc890f311b175a555b5d9641025b35ab6751 100644 (file)
@@ -385,6 +385,7 @@ static bool nft_hash_estimate(const struct nft_set_desc *desc, u32 features,
        }
 
        est->lookup = NFT_SET_CLASS_O_1;
+       est->space  = NFT_SET_CLASS_O_N;
 
        return true;
 }
index 2b6ea10c4bbd31db8ce0e10c1860150c997a50bf..3387ed7dd2317e65e6b381daac978730fc3018a6 100644 (file)
@@ -292,6 +292,7 @@ static bool nft_rbtree_estimate(const struct nft_set_desc *desc, u32 features,
                est->size = nsize;
 
        est->lookup = NFT_SET_CLASS_O_LOG_N;
+       est->space  = NFT_SET_CLASS_O_N;
 
        return true;
 }