diff options
author | Patrick McHardy <kaber@trash.net> | 2013-10-10 23:35:40 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-10-14 17:16:09 +0200 |
commit | cb7dbfd0390c9e244339f3270fe8649568241812 (patch) | |
tree | 3e4587f757c08b59e936d4f45d0d2e7c25b3f93e /net/netfilter/nf_tables_core.c | |
parent | ef1f7df9170dbd875ce198ba84e6ab80f6fc139e (diff) | |
download | op-kernel-dev-cb7dbfd0390c9e244339f3270fe8649568241812.zip op-kernel-dev-cb7dbfd0390c9e244339f3270fe8649568241812.tar.gz |
netfilter: nf_tables: add optimized data comparison for small values
Add an optimized version of nft_data_cmp() that only handles values of to
4 bytes length.
This patch includes original Patrick McHardy's patch entitled (nf_tables:
inline nft_cmp_fast_eval() into main evaluation loop).
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nf_tables_core.c')
-rw-r--r-- | net/netfilter/nf_tables_core.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index fd0ecd3..2400018 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c @@ -20,6 +20,18 @@ #include <net/netfilter/nf_tables_core.h> #include <net/netfilter/nf_tables.h> +static void nft_cmp_fast_eval(const struct nft_expr *expr, + struct nft_data data[NFT_REG_MAX + 1]) +{ + const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr); + u32 mask; + + mask = ~0U >> (sizeof(priv->data) * BITS_PER_BYTE - priv->len); + if ((data[priv->sreg].data[0] & mask) == priv->data) + return; + data[NFT_REG_VERDICT].verdict = NFT_BREAK; +} + unsigned int nft_do_chain(const struct nf_hook_ops *ops, struct sk_buff *skb, const struct net_device *in, @@ -48,7 +60,11 @@ next_rule: data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; list_for_each_entry_continue_rcu(rule, &chain->rules, list) { nft_rule_for_each_expr(expr, last, rule) { - expr->ops->eval(expr, data, &pkt); + if (expr->ops == &nft_cmp_fast_ops) + nft_cmp_fast_eval(expr, data); + else + expr->ops->eval(expr, data, &pkt); + if (data[NFT_REG_VERDICT].verdict != NFT_CONTINUE) break; } |