lkml.org 
[lkml]   [2020]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 241/639] netfilter: nft_set_hash: fix lookups with fixed size hash on big endian
    Date
    From: Pablo Neira Ayuso <pablo@netfilter.org>

    [ Upstream commit 3b02b0adc242a72b5e46019b6a9e4f84823592f6 ]

    Call jhash_1word() for the 4-bytes key case from the insertion and
    deactivation path, otherwise big endian arch set lookups fail.

    Fixes: 446a8268b7f5 ("netfilter: nft_set_hash: add lookup variant for fixed size hashtable")
    Reported-by: Florian Westphal <fw@strlen.de>
    Tested-by: Florian Westphal <fw@strlen.de>
    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/netfilter/nft_set_hash.c | 23 +++++++++++++++++++----
    1 file changed, 19 insertions(+), 4 deletions(-)

    diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
    index 015124e649cbd..8dde4bfe8b8a4 100644
    --- a/net/netfilter/nft_set_hash.c
    +++ b/net/netfilter/nft_set_hash.c
    @@ -488,6 +488,23 @@ static bool nft_hash_lookup_fast(const struct net *net,
    return false;
    }

    +static u32 nft_jhash(const struct nft_set *set, const struct nft_hash *priv,
    + const struct nft_set_ext *ext)
    +{
    + const struct nft_data *key = nft_set_ext_key(ext);
    + u32 hash, k1;
    +
    + if (set->klen == 4) {
    + k1 = *(u32 *)key;
    + hash = jhash_1word(k1, priv->seed);
    + } else {
    + hash = jhash(key, set->klen, priv->seed);
    + }
    + hash = reciprocal_scale(hash, priv->buckets);
    +
    + return hash;
    +}
    +
    static int nft_hash_insert(const struct net *net, const struct nft_set *set,
    const struct nft_set_elem *elem,
    struct nft_set_ext **ext)
    @@ -497,8 +514,7 @@ static int nft_hash_insert(const struct net *net, const struct nft_set *set,
    u8 genmask = nft_genmask_next(net);
    u32 hash;

    - hash = jhash(nft_set_ext_key(&this->ext), set->klen, priv->seed);
    - hash = reciprocal_scale(hash, priv->buckets);
    + hash = nft_jhash(set, priv, &this->ext);
    hlist_for_each_entry(he, &priv->table[hash], node) {
    if (!memcmp(nft_set_ext_key(&this->ext),
    nft_set_ext_key(&he->ext), set->klen) &&
    @@ -537,8 +553,7 @@ static void *nft_hash_deactivate(const struct net *net,
    u8 genmask = nft_genmask_next(net);
    u32 hash;

    - hash = jhash(nft_set_ext_key(&this->ext), set->klen, priv->seed);
    - hash = reciprocal_scale(hash, priv->buckets);
    + hash = nft_jhash(set, priv, &this->ext);
    hlist_for_each_entry(he, &priv->table[hash], node) {
    if (!memcmp(nft_set_ext_key(&this->ext), &elem->key.val,
    set->klen) &&
    --
    2.20.1


    \
     
     \ /
      Last update: 2020-01-24 12:13    [W:2.246 / U:1.832 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site