aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Neuschäfer <j.neuschaefer@gmx.net>2018-07-26 01:56:45 +0200
committerJonathan Neuschäfer <j.neuschaefer@gmx.net>2018-07-26 01:58:40 +0200
commit25d757f8a0f0c832defd0bc4dc555a230f281fd3 (patch)
treeae03656bc84647ca479894aefd4f1ff740aca376
parentLinux 4.18-rc6 (diff)
downloadlinux-dev-25d757f8a0f0c832defd0bc4dc555a230f281fd3.tar.xz
linux-dev-25d757f8a0f0c832defd0bc4dc555a230f281fd3.zip
rhashtable: Change the seed to 128 bits
The SipHash algorithm relies on a 128-bit hash seed. In order to use SipHash with rhashtable, change the seed used in rhashtable to 128 bits. Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
-rw-r--r--include/linux/rhashtable.h21
-rw-r--r--lib/rhashtable.c17
-rw-r--r--lib/test_rhashtable.c6
-rw-r--r--net/core/xdp.c2
-rw-r--r--net/ipv4/ip_fragment.c8
-rw-r--r--net/ipv6/reassembly.c8
-rw-r--r--net/mac80211/mesh_pathtbl.c4
-rw-r--r--net/netfilter/nf_tables_api.c10
-rw-r--r--net/netlink/af_netlink.c4
-rw-r--r--net/sctp/input.c12
10 files changed, 53 insertions, 39 deletions
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 4e1f535c2034..063e7fa7e9ca 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -73,6 +73,10 @@ struct rhlist_head {
struct rhlist_head __rcu *next;
};
+struct rhash_rnd {
+ u64 data[2];
+};
+
/**
* struct bucket_table - Table of hash buckets
* @size: Number of hash buckets
@@ -91,7 +95,7 @@ struct bucket_table {
unsigned int size;
unsigned int nest;
unsigned int rehash;
- u32 hash_rnd;
+ struct rhash_rnd hash_rnd;
unsigned int locks_mask;
spinlock_t *locks;
struct list_head walkers;
@@ -112,11 +116,14 @@ struct rhashtable_compare_arg {
const void *key;
};
-typedef u32 (*rht_hashfn_t)(const void *data, u32 len, u32 seed);
-typedef u32 (*rht_obj_hashfn_t)(const void *data, u32 len, u32 seed);
+typedef u32 (*rht_hashfn_t)(const void *data, u32 len, struct rhash_rnd seed);
+typedef u32 (*rht_obj_hashfn_t)(const void *data, u32 len, struct rhash_rnd seed);
typedef int (*rht_obj_cmpfn_t)(struct rhashtable_compare_arg *arg,
const void *obj);
+u32 rhashtable_jhash(const void *key, u32 length, struct rhash_rnd seed);
+u32 rhashtable_jhash2(const void *key, u32 length, struct rhash_rnd seed);
+
struct rhashtable;
/**
@@ -242,7 +249,7 @@ static inline unsigned int rht_bucket_index(const struct bucket_table *tbl,
static inline unsigned int rht_key_get_hash(struct rhashtable *ht,
const void *key, const struct rhashtable_params params,
- unsigned int hash_rnd)
+ struct rhash_rnd hash_rnd)
{
unsigned int hash;
@@ -255,16 +262,16 @@ static inline unsigned int rht_key_get_hash(struct rhashtable *ht,
if (params.hashfn)
hash = params.hashfn(key, key_len, hash_rnd);
else if (key_len & (sizeof(u32) - 1))
- hash = jhash(key, key_len, hash_rnd);
+ hash = jhash(key, key_len, hash_rnd.data[0]);
else
- hash = jhash2(key, key_len / sizeof(u32), hash_rnd);
+ hash = jhash2(key, key_len / sizeof(u32), hash_rnd.data[0]);
} else {
unsigned int key_len = ht->p.key_len;
if (params.hashfn)
hash = params.hashfn(key, key_len, hash_rnd);
else
- hash = jhash(key, key_len, hash_rnd);
+ hash = jhash(key, key_len, hash_rnd.data[0]);
}
return hash;
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index e5c8586cf717..97ee2a5b77fc 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -203,7 +203,7 @@ static struct bucket_table *bucket_table_alloc(struct rhashtable *ht,
INIT_LIST_HEAD(&tbl->walkers);
- tbl->hash_rnd = get_random_u32();
+ get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd));
for (i = 0; i < nbuckets; i++)
INIT_RHT_NULLS_HEAD(tbl->buckets[i], ht, i);
@@ -976,10 +976,17 @@ static size_t rounded_hashtable_size(const struct rhashtable_params *params)
return retsize;
}
-static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed)
+u32 rhashtable_jhash(const void *key, u32 length, struct rhash_rnd seed)
{
- return jhash2(key, length, seed);
+ return jhash(key, length, seed.data[0]);
}
+EXPORT_SYMBOL_GPL(rhashtable_jhash);
+
+u32 rhashtable_jhash2(const void *key, u32 length, struct rhash_rnd seed)
+{
+ return jhash2(key, length, seed.data[0]);
+}
+EXPORT_SYMBOL_GPL(rhashtable_jhash2);
/**
* rhashtable_init - initialize a new hash table
@@ -1011,7 +1018,7 @@ static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed)
* struct rhash_head node;
* };
*
- * u32 my_hash_fn(const void *data, u32 len, u32 seed)
+ * u32 my_hash_fn(const void *data, u32 len, struct rhash_rnd seed)
* {
* struct test_obj *obj = data;
*
@@ -1065,7 +1072,7 @@ int rhashtable_init(struct rhashtable *ht,
ht->key_len = ht->p.key_len;
if (!params->hashfn) {
- ht->p.hashfn = jhash;
+ ht->p.hashfn = rhashtable_jhash;
if (!(ht->key_len & (sizeof(u32) - 1))) {
ht->key_len /= sizeof(u32);
diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c
index fb6968109113..c6d7c77036f9 100644
--- a/lib/test_rhashtable.c
+++ b/lib/test_rhashtable.c
@@ -79,7 +79,7 @@ struct thread_data {
struct test_obj *objs;
};
-static u32 my_hashfn(const void *data, u32 len, u32 seed)
+static u32 my_hashfn(const void *data, u32 len, struct rhash_rnd seed)
{
const struct test_obj_rhl *obj = data;
@@ -98,7 +98,7 @@ static struct rhashtable_params test_rht_params = {
.head_offset = offsetof(struct test_obj, node),
.key_offset = offsetof(struct test_obj, value),
.key_len = sizeof(struct test_obj_val),
- .hashfn = jhash,
+ .hashfn = rhashtable_jhash,
.nulls_base = (3U << RHT_BASE_SHIFT),
};
@@ -106,7 +106,7 @@ static struct rhashtable_params test_rht_params_dup = {
.head_offset = offsetof(struct test_obj_rhl, list_node),
.key_offset = offsetof(struct test_obj_rhl, value),
.key_len = sizeof(struct test_obj_val),
- .hashfn = jhash,
+ .hashfn = rhashtable_jhash,
.obj_hashfn = my_hashfn,
.obj_cmpfn = my_cmpfn,
.nelem_hint = 128,
diff --git a/net/core/xdp.c b/net/core/xdp.c
index 9d1f22072d5d..0068e29f2e86 100644
--- a/net/core/xdp.c
+++ b/net/core/xdp.c
@@ -37,7 +37,7 @@ struct xdp_mem_allocator {
struct rcu_head rcu;
};
-static u32 xdp_mem_id_hashfn(const void *data, u32 len, u32 seed)
+static u32 xdp_mem_id_hashfn(const void *data, u32 len, struct rhash_rnd seed)
{
const u32 *k = data;
const u32 key = *k;
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 8e9528ebaa8e..ed1910d0ac9a 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -830,18 +830,18 @@ static struct pernet_operations ip4_frags_ops = {
};
-static u32 ip4_key_hashfn(const void *data, u32 len, u32 seed)
+static u32 ip4_key_hashfn(const void *data, u32 len, struct rhash_rnd seed)
{
return jhash2(data,
- sizeof(struct frag_v4_compare_key) / sizeof(u32), seed);
+ sizeof(struct frag_v4_compare_key) / sizeof(u32), seed.data[0]);
}
-static u32 ip4_obj_hashfn(const void *data, u32 len, u32 seed)
+static u32 ip4_obj_hashfn(const void *data, u32 len, struct rhash_rnd seed)
{
const struct inet_frag_queue *fq = data;
return jhash2((const u32 *)&fq->key.v4,
- sizeof(struct frag_v4_compare_key) / sizeof(u32), seed);
+ sizeof(struct frag_v4_compare_key) / sizeof(u32), seed.data[0]);
}
static int ip4_obj_cmpfn(struct rhashtable_compare_arg *arg, const void *ptr)
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index b939b94e7e91..f90f690e5a3d 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -696,18 +696,18 @@ static struct pernet_operations ip6_frags_ops = {
.exit = ipv6_frags_exit_net,
};
-static u32 ip6_key_hashfn(const void *data, u32 len, u32 seed)
+static u32 ip6_key_hashfn(const void *data, u32 len, struct rhash_rnd seed)
{
return jhash2(data,
- sizeof(struct frag_v6_compare_key) / sizeof(u32), seed);
+ sizeof(struct frag_v6_compare_key) / sizeof(u32), seed.data[0]);
}
-static u32 ip6_obj_hashfn(const void *data, u32 len, u32 seed)
+static u32 ip6_obj_hashfn(const void *data, u32 len, struct rhash_rnd seed)
{
const struct inet_frag_queue *fq = data;
return jhash2((const u32 *)&fq->key.v6,
- sizeof(struct frag_v6_compare_key) / sizeof(u32), seed);
+ sizeof(struct frag_v6_compare_key) / sizeof(u32), seed.data[0]);
}
static int ip6_obj_cmpfn(struct rhashtable_compare_arg *arg, const void *ptr)
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index a5125624a76d..7692d8cf394f 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -20,10 +20,10 @@
static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath);
-static u32 mesh_table_hash(const void *addr, u32 len, u32 seed)
+static u32 mesh_table_hash(const void *addr, u32 len, struct rhash_rnd seed)
{
/* Use last four bytes of hw addr as hash index */
- return jhash_1word(*(u32 *)(addr+2), seed);
+ return jhash_1word(*(u32 *)(addr+2), seed.data[0]);
}
static const struct rhashtable_params mesh_rht_params = {
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 896d4a36081d..843a444140e9 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -34,8 +34,8 @@ enum {
NFT_VALIDATE_DO,
};
-static u32 nft_chain_hash(const void *data, u32 len, u32 seed);
-static u32 nft_chain_hash_obj(const void *data, u32 len, u32 seed);
+static u32 nft_chain_hash(const void *data, u32 len, struct rhash_rnd seed);
+static u32 nft_chain_hash_obj(const void *data, u32 len, struct rhash_rnd seed);
static int nft_chain_hash_cmp(struct rhashtable_compare_arg *, const void *);
static const struct rhashtable_params nft_chain_ht_params = {
@@ -734,14 +734,14 @@ err:
return ret;
}
-static u32 nft_chain_hash(const void *data, u32 len, u32 seed)
+static u32 nft_chain_hash(const void *data, u32 len, struct rhash_rnd seed)
{
const char *name = data;
- return jhash(name, strlen(name), seed);
+ return jhash(name, strlen(name), seed.data[0]);
}
-static u32 nft_chain_hash_obj(const void *data, u32 len, u32 seed)
+static u32 nft_chain_hash_obj(const void *data, u32 len, struct rhash_rnd seed)
{
const struct nft_chain *chain = data;
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 393573a99a5a..e20ead807123 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2718,13 +2718,13 @@ static struct pernet_operations __net_initdata netlink_net_ops = {
.exit = netlink_net_exit,
};
-static inline u32 netlink_hash(const void *data, u32 len, u32 seed)
+static inline u32 netlink_hash(const void *data, u32 len, struct rhash_rnd seed)
{
const struct netlink_sock *nlk = data;
struct netlink_compare_arg arg;
netlink_compare_arg_init(&arg, sock_net(&nlk->sk), nlk->portid);
- return jhash2((u32 *)&arg, netlink_compare_arg_len / sizeof(u32), seed);
+ return jhash2((u32 *)&arg, netlink_compare_arg_len / sizeof(u32), seed.data[0]);
}
static const struct rhashtable_params netlink_rhashtable_params = {
diff --git a/net/sctp/input.c b/net/sctp/input.c
index ba8a6e6c36fa..4f4a9f8e2d5c 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -824,7 +824,7 @@ out:
return err;
}
-static inline __u32 sctp_hash_obj(const void *data, u32 len, u32 seed)
+static inline __u32 sctp_hash_obj(const void *data, u32 len, struct rhash_rnd seed)
{
const struct sctp_transport *t = data;
const union sctp_addr *paddr = &t->ipaddr;
@@ -833,15 +833,15 @@ static inline __u32 sctp_hash_obj(const void *data, u32 len, u32 seed)
__u32 addr;
if (paddr->sa.sa_family == AF_INET6)
- addr = jhash(&paddr->v6.sin6_addr, 16, seed);
+ addr = jhash(&paddr->v6.sin6_addr, 16, seed.data[0]);
else
addr = (__force __u32)paddr->v4.sin_addr.s_addr;
return jhash_3words(addr, ((__force __u32)paddr->v4.sin_port) << 16 |
- (__force __u32)lport, net_hash_mix(net), seed);
+ (__force __u32)lport, net_hash_mix(net), seed.data[0]);
}
-static inline __u32 sctp_hash_key(const void *data, u32 len, u32 seed)
+static inline __u32 sctp_hash_key(const void *data, u32 len, struct rhash_rnd seed)
{
const struct sctp_hash_cmp_arg *x = data;
const union sctp_addr *paddr = x->paddr;
@@ -850,12 +850,12 @@ static inline __u32 sctp_hash_key(const void *data, u32 len, u32 seed)
__u32 addr;
if (paddr->sa.sa_family == AF_INET6)
- addr = jhash(&paddr->v6.sin6_addr, 16, seed);
+ addr = jhash(&paddr->v6.sin6_addr, 16, seed.data[0]);
else
addr = (__force __u32)paddr->v4.sin_addr.s_addr;
return jhash_3words(addr, ((__force __u32)paddr->v4.sin_port) << 16 |
- (__force __u32)lport, net_hash_mix(net), seed);
+ (__force __u32)lport, net_hash_mix(net), seed.data[0]);
}
static const struct rhashtable_params sctp_hash_params = {