From patchwork Sat Mar 21 15:38:10 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick McHardy X-Patchwork-Id: 452956 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 852F6140142 for ; Sun, 22 Mar 2015 02:38:45 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751476AbbCUPib (ORCPT ); Sat, 21 Mar 2015 11:38:31 -0400 Received: from stinky.trash.net ([213.144.137.162]:46537 "EHLO stinky.trash.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751452AbbCUPi1 (ORCPT ); Sat, 21 Mar 2015 11:38:27 -0400 Received: from acer.Home (localhost [127.0.0.1]) by stinky.trash.net (Postfix) with ESMTP id A8B709D2E0; Sat, 21 Mar 2015 16:38:24 +0100 (MET) From: Patrick McHardy To: pablo@netfilter.org Cc: davem@davemloft.net, herbert@gondor.apana.org.au, tgraf@suug.ch, netfilter-devel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH 2/2] netfilter: nft_hash: convert to use rhashtable callbacks Date: Sat, 21 Mar 2015 15:38:10 +0000 Message-Id: <1426952290-18962-3-git-send-email-kaber@trash.net> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1426952290-18962-1-git-send-email-kaber@trash.net> References: <1426952290-18962-1-git-send-email-kaber@trash.net> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org A following patch will convert sets to use so called set extensions, where the key is not located in a fixed position anymore. This will require rhashtable hashing and comparison callbacks to be used. As preparation, convert nft_hash to use these callbacks without any functional changes. Signed-off-by: Patrick McHardy --- net/netfilter/nft_hash.c | 54 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c index e815940..4de73b3 100644 --- a/net/netfilter/nft_hash.c +++ b/net/netfilter/nft_hash.c @@ -33,16 +33,50 @@ struct nft_hash_elem { struct nft_data data[]; }; +struct nft_hash_cmp_arg { + const struct nft_set *set; + const struct nft_data *key; +}; + static const struct rhashtable_params nft_hash_params; +static inline u32 nft_hash_key(const void *data, u32 len, u32 seed) +{ + const struct nft_hash_cmp_arg *arg = data; + + return jhash(arg->key, len, seed); +} + +static inline u32 nft_hash_obj(const void *data, u32 len, u32 seed) +{ + const struct nft_hash_elem *he = data; + + return jhash(&he->key, len, seed); +} + +static inline int nft_hash_cmp(struct rhashtable_compare_arg *arg, + const void *ptr) +{ + const struct nft_hash_cmp_arg *x = arg->key; + const struct nft_hash_elem *he = ptr; + + if (nft_data_cmp(&he->key, x->key, x->set->klen)) + return 1; + return 0; +} + static bool nft_hash_lookup(const struct nft_set *set, const struct nft_data *key, struct nft_data *data) { struct nft_hash *priv = nft_set_priv(set); const struct nft_hash_elem *he; + struct nft_hash_cmp_arg arg = { + .set = set, + .key = key, + }; - he = rhashtable_lookup_fast(&priv->ht, key, nft_hash_params); + he = rhashtable_lookup_fast(&priv->ht, &arg, nft_hash_params); if (he && set->flags & NFT_SET_MAP) nft_data_copy(data, he->data); @@ -54,6 +88,10 @@ static int nft_hash_insert(const struct nft_set *set, { struct nft_hash *priv = nft_set_priv(set); struct nft_hash_elem *he; + struct nft_hash_cmp_arg arg = { + .set = set, + .key = &elem->key, + }; unsigned int size; int err; @@ -72,7 +110,8 @@ static int nft_hash_insert(const struct nft_set *set, if (set->flags & NFT_SET_MAP) nft_data_copy(he->data, &elem->data); - err = rhashtable_insert_fast(&priv->ht, &he->node, nft_hash_params); + err = rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node, + nft_hash_params); if (err) kfree(he); @@ -102,8 +141,12 @@ static int nft_hash_get(const struct nft_set *set, struct nft_set_elem *elem) { struct nft_hash *priv = nft_set_priv(set); struct nft_hash_elem *he; + struct nft_hash_cmp_arg arg = { + .set = set, + .key = &elem->key, + }; - he = rhashtable_lookup_fast(&priv->ht, &elem->key, nft_hash_params); + he = rhashtable_lookup_fast(&priv->ht, &arg, nft_hash_params); if (!he) return -ENOENT; @@ -172,8 +215,9 @@ static unsigned int nft_hash_privsize(const struct nlattr * const nla[]) static const struct rhashtable_params nft_hash_params = { .head_offset = offsetof(struct nft_hash_elem, node), - .key_offset = offsetof(struct nft_hash_elem, key), - .hashfn = jhash, + .hashfn = nft_hash_key, + .obj_hashfn = nft_hash_obj, + .obj_cmpfn = nft_hash_cmp, }; static int nft_hash_init(const struct nft_set *set,