aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-10-19 19:45:46 -0400
committerDavid S. Miller <davem@davemloft.net>2013-10-19 19:45:46 -0400
commit7dcade390860712551a4feb080911d5002226188 (patch)
tree68768a3e760a90b2b13a8e7a83d573c0e63a4a35 /net
parent53481da372851a5506deb5247302f75459b472b4 (diff)
parente34c9a69970d8664a36b46e6445a7cc879111cfd (diff)
Merge branch 'net_get_random_once'
Hannes Frederic Sowa says: ==================== This series implements support for delaying the initialization of secret keys, e.g. used for hashing, for as long as possible. This functionality is implemented by a new macro, net_get_random_bytes. I already used it to protect the socket hashes, the syncookie secret (most important) and the tcp_fastopen secrets. Changelog: v2) Use static_keys in net_get_random_once to have as minimal impact to the fast-path as possible. v3) added patch "static_key: WARN on usage before jump_label_init was called": Patch "x86/jump_label: expect default_nop if static_key gets enabled on boot-up" relaxes the checks for using static_key primitives before jump_label_init. So tighten them first. v4) Update changelog on the patch "static_key: WARN on usage before jump_label_init was called" Included patches: ipv4: split inet_ehashfn to hash functions per compilation unit ipv6: split inet6_ehashfn to hash functions per compilation unit static_key: WARN on usage before jump_label_init was called x86/jump_label: expect default_nop if static_key gets enabled on boot-up net: introduce new macro net_get_random_once inet: split syncookie keys for ipv4 and ipv6 and initialize with net_get_random_once inet: convert inet_ehash_secret and ipv6_hash_secret to net_get_random_once tcp: switch tcp_fastopen key generation to net_get_random_once net: switch net_secret key generation to net_get_random_once ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/secure_seq.c14
-rw-r--r--net/core/utils.c48
-rw-r--r--net/ipv4/af_inet.c27
-rw-r--r--net/ipv4/inet_hashtables.c25
-rw-r--r--net/ipv4/syncookies.c15
-rw-r--r--net/ipv4/sysctl_net_ipv4.c5
-rw-r--r--net/ipv4/tcp_fastopen.c27
-rw-r--r--net/ipv4/udp.c20
-rw-r--r--net/ipv6/af_inet6.c5
-rw-r--r--net/ipv6/inet6_hashtables.c33
-rw-r--r--net/ipv6/syncookies.c12
-rw-r--r--net/ipv6/udp.c31
-rw-r--r--net/rds/connection.c12
13 files changed, 195 insertions, 79 deletions
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
index 3f1ec1586ae1..b02fd16b8942 100644
--- a/net/core/secure_seq.c
+++ b/net/core/secure_seq.c
@@ -7,6 +7,7 @@
7#include <linux/hrtimer.h> 7#include <linux/hrtimer.h>
8#include <linux/ktime.h> 8#include <linux/ktime.h>
9#include <linux/string.h> 9#include <linux/string.h>
10#include <linux/net.h>
10 11
11#include <net/secure_seq.h> 12#include <net/secure_seq.h>
12 13
@@ -16,18 +17,7 @@ static u32 net_secret[NET_SECRET_SIZE] ____cacheline_aligned;
16 17
17static void net_secret_init(void) 18static void net_secret_init(void)
18{ 19{
19 u32 tmp; 20 net_get_random_once(net_secret, sizeof(net_secret));
20 int i;
21
22 if (likely(net_secret[0]))
23 return;
24
25 for (i = NET_SECRET_SIZE; i > 0;) {
26 do {
27 get_random_bytes(&tmp, sizeof(tmp));
28 } while (!tmp);
29 cmpxchg(&net_secret[--i], 0, tmp);
30 }
31} 21}
32 22
33#ifdef CONFIG_INET 23#ifdef CONFIG_INET
diff --git a/net/core/utils.c b/net/core/utils.c
index aa88e23fc87a..bf09371e19b1 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -338,3 +338,51 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb,
338 csum_unfold(*sum))); 338 csum_unfold(*sum)));
339} 339}
340EXPORT_SYMBOL(inet_proto_csum_replace16); 340EXPORT_SYMBOL(inet_proto_csum_replace16);
341
342struct __net_random_once_work {
343 struct work_struct work;
344 struct static_key *key;
345};
346
347static void __net_random_once_deferred(struct work_struct *w)
348{
349 struct __net_random_once_work *work =
350 container_of(w, struct __net_random_once_work, work);
351 if (!static_key_enabled(work->key))
352 static_key_slow_inc(work->key);
353 kfree(work);
354}
355
356static void __net_random_once_disable_jump(struct static_key *key)
357{
358 struct __net_random_once_work *w;
359
360 w = kmalloc(sizeof(*w), GFP_ATOMIC);
361 if (!w)
362 return;
363
364 INIT_WORK(&w->work, __net_random_once_deferred);
365 w->key = key;
366 schedule_work(&w->work);
367}
368
369bool __net_get_random_once(void *buf, int nbytes, bool *done,
370 struct static_key *done_key)
371{
372 static DEFINE_SPINLOCK(lock);
373
374 spin_lock_bh(&lock);
375 if (*done) {
376 spin_unlock_bh(&lock);
377 return false;
378 }
379
380 get_random_bytes(buf, nbytes);
381 *done = true;
382 spin_unlock_bh(&lock);
383
384 __net_random_once_disable_jump(done_key);
385
386 return true;
387}
388EXPORT_SYMBOL(__net_get_random_once);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 4049906010f7..9433a6186f54 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -245,29 +245,6 @@ out:
245} 245}
246EXPORT_SYMBOL(inet_listen); 246EXPORT_SYMBOL(inet_listen);
247 247
248u32 inet_ehash_secret __read_mostly;
249EXPORT_SYMBOL(inet_ehash_secret);
250
251u32 ipv6_hash_secret __read_mostly;
252EXPORT_SYMBOL(ipv6_hash_secret);
253
254/*
255 * inet_ehash_secret must be set exactly once, and to a non nul value
256 * ipv6_hash_secret must be set exactly once.
257 */
258void build_ehash_secret(void)
259{
260 u32 rnd;
261
262 do {
263 get_random_bytes(&rnd, sizeof(rnd));
264 } while (rnd == 0);
265
266 if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0)
267 get_random_bytes(&ipv6_hash_secret, sizeof(ipv6_hash_secret));
268}
269EXPORT_SYMBOL(build_ehash_secret);
270
271/* 248/*
272 * Create an inet socket. 249 * Create an inet socket.
273 */ 250 */
@@ -284,10 +261,6 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,
284 int try_loading_module = 0; 261 int try_loading_module = 0;
285 int err; 262 int err;
286 263
287 if (unlikely(!inet_ehash_secret))
288 if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
289 build_ehash_secret();
290
291 sock->state = SS_UNCONNECTED; 264 sock->state = SS_UNCONNECTED;
292 265
293 /* Look for the requested type/protocol pair. */ 266 /* Look for the requested type/protocol pair. */
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index a4b66bbe4f21..8b9cf279450d 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -24,6 +24,31 @@
24#include <net/secure_seq.h> 24#include <net/secure_seq.h>
25#include <net/ip.h> 25#include <net/ip.h>
26 26
27static unsigned int inet_ehashfn(struct net *net, const __be32 laddr,
28 const __u16 lport, const __be32 faddr,
29 const __be16 fport)
30{
31 static u32 inet_ehash_secret __read_mostly;
32
33 net_get_random_once(&inet_ehash_secret, sizeof(inet_ehash_secret));
34
35 return __inet_ehashfn(laddr, lport, faddr, fport,
36 inet_ehash_secret + net_hash_mix(net));
37}
38
39
40static unsigned int inet_sk_ehashfn(const struct sock *sk)
41{
42 const struct inet_sock *inet = inet_sk(sk);
43 const __be32 laddr = inet->inet_rcv_saddr;
44 const __u16 lport = inet->inet_num;
45 const __be32 faddr = inet->inet_daddr;
46 const __be16 fport = inet->inet_dport;
47 struct net *net = sock_net(sk);
48
49 return inet_ehashfn(net, laddr, lport, faddr, fport);
50}
51
27/* 52/*
28 * Allocate and initialize a new local port bind bucket. 53 * Allocate and initialize a new local port bind bucket.
29 * The bindhash mutex for snum's hash chain must be held here. 54 * The bindhash mutex for snum's hash chain must be held here.
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 3b64c59b4109..b95331e6c077 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -25,15 +25,7 @@
25 25
26extern int sysctl_tcp_syncookies; 26extern int sysctl_tcp_syncookies;
27 27
28__u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS]; 28static u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS];
29EXPORT_SYMBOL(syncookie_secret);
30
31static __init int init_syncookies(void)
32{
33 get_random_bytes(syncookie_secret, sizeof(syncookie_secret));
34 return 0;
35}
36__initcall(init_syncookies);
37 29
38#define COOKIEBITS 24 /* Upper bits store count */ 30#define COOKIEBITS 24 /* Upper bits store count */
39#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1) 31#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
@@ -44,8 +36,11 @@ static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS],
44static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, 36static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport,
45 u32 count, int c) 37 u32 count, int c)
46{ 38{
47 __u32 *tmp = __get_cpu_var(ipv4_cookie_scratch); 39 __u32 *tmp;
40
41 net_get_random_once(syncookie_secret, sizeof(syncookie_secret));
48 42
43 tmp = __get_cpu_var(ipv4_cookie_scratch);
49 memcpy(tmp + 4, syncookie_secret[c], sizeof(syncookie_secret[c])); 44 memcpy(tmp + 4, syncookie_secret[c], sizeof(syncookie_secret[c]));
50 tmp[0] = (__force u32)saddr; 45 tmp[0] = (__force u32)saddr;
51 tmp[1] = (__force u32)daddr; 46 tmp[1] = (__force u32)daddr;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index c08f096d46b5..4b161d5aba0b 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -274,6 +274,11 @@ static int proc_tcp_fastopen_key(struct ctl_table *ctl, int write,
274 ret = -EINVAL; 274 ret = -EINVAL;
275 goto bad_key; 275 goto bad_key;
276 } 276 }
277 /* Generate a dummy secret but don't publish it. This
278 * is needed so we don't regenerate a new key on the
279 * first invocation of tcp_fastopen_cookie_gen
280 */
281 tcp_fastopen_init_key_once(false);
277 tcp_fastopen_reset_cipher(user_key, TCP_FASTOPEN_KEY_LENGTH); 282 tcp_fastopen_reset_cipher(user_key, TCP_FASTOPEN_KEY_LENGTH);
278 } 283 }
279 284
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index ab7bd35bb312..766032b4a6c3 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -14,6 +14,20 @@ struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;
14 14
15static DEFINE_SPINLOCK(tcp_fastopen_ctx_lock); 15static DEFINE_SPINLOCK(tcp_fastopen_ctx_lock);
16 16
17void tcp_fastopen_init_key_once(bool publish)
18{
19 static u8 key[TCP_FASTOPEN_KEY_LENGTH];
20
21 /* tcp_fastopen_reset_cipher publishes the new context
22 * atomically, so we allow this race happening here.
23 *
24 * All call sites of tcp_fastopen_cookie_gen also check
25 * for a valid cookie, so this is an acceptable risk.
26 */
27 if (net_get_random_once(key, sizeof(key)) && publish)
28 tcp_fastopen_reset_cipher(key, sizeof(key));
29}
30
17static void tcp_fastopen_ctx_free(struct rcu_head *head) 31static void tcp_fastopen_ctx_free(struct rcu_head *head)
18{ 32{
19 struct tcp_fastopen_context *ctx = 33 struct tcp_fastopen_context *ctx =
@@ -70,6 +84,8 @@ void tcp_fastopen_cookie_gen(__be32 src, __be32 dst,
70 __be32 path[4] = { src, dst, 0, 0 }; 84 __be32 path[4] = { src, dst, 0, 0 };
71 struct tcp_fastopen_context *ctx; 85 struct tcp_fastopen_context *ctx;
72 86
87 tcp_fastopen_init_key_once(true);
88
73 rcu_read_lock(); 89 rcu_read_lock();
74 ctx = rcu_dereference(tcp_fastopen_ctx); 90 ctx = rcu_dereference(tcp_fastopen_ctx);
75 if (ctx) { 91 if (ctx) {
@@ -78,14 +94,3 @@ void tcp_fastopen_cookie_gen(__be32 src, __be32 dst,
78 } 94 }
79 rcu_read_unlock(); 95 rcu_read_unlock();
80} 96}
81
82static int __init tcp_fastopen_init(void)
83{
84 __u8 key[TCP_FASTOPEN_KEY_LENGTH];
85
86 get_random_bytes(key, sizeof(key));
87 tcp_fastopen_reset_cipher(key, sizeof(key));
88 return 0;
89}
90
91late_initcall(tcp_fastopen_init);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 9f27bb800607..89909dd730dd 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -407,6 +407,18 @@ static inline int compute_score2(struct sock *sk, struct net *net,
407 return score; 407 return score;
408} 408}
409 409
410static unsigned int udp_ehashfn(struct net *net, const __be32 laddr,
411 const __u16 lport, const __be32 faddr,
412 const __be16 fport)
413{
414 static u32 udp_ehash_secret __read_mostly;
415
416 net_get_random_once(&udp_ehash_secret, sizeof(udp_ehash_secret));
417
418 return __inet_ehashfn(laddr, lport, faddr, fport,
419 udp_ehash_secret + net_hash_mix(net));
420}
421
410 422
411/* called with read_rcu_lock() */ 423/* called with read_rcu_lock() */
412static struct sock *udp4_lib_lookup2(struct net *net, 424static struct sock *udp4_lib_lookup2(struct net *net,
@@ -430,8 +442,8 @@ begin:
430 badness = score; 442 badness = score;
431 reuseport = sk->sk_reuseport; 443 reuseport = sk->sk_reuseport;
432 if (reuseport) { 444 if (reuseport) {
433 hash = inet_ehashfn(net, daddr, hnum, 445 hash = udp_ehashfn(net, daddr, hnum,
434 saddr, sport); 446 saddr, sport);
435 matches = 1; 447 matches = 1;
436 } 448 }
437 } else if (score == badness && reuseport) { 449 } else if (score == badness && reuseport) {
@@ -511,8 +523,8 @@ begin:
511 badness = score; 523 badness = score;
512 reuseport = sk->sk_reuseport; 524 reuseport = sk->sk_reuseport;
513 if (reuseport) { 525 if (reuseport) {
514 hash = inet_ehashfn(net, daddr, hnum, 526 hash = udp_ehashfn(net, daddr, hnum,
515 saddr, sport); 527 saddr, sport);
516 matches = 1; 528 matches = 1;
517 } 529 }
518 } else if (score == badness && reuseport) { 530 } else if (score == badness && reuseport) {
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index a2cb07cd3850..20af1fb81c83 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -110,11 +110,6 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
110 int try_loading_module = 0; 110 int try_loading_module = 0;
111 int err; 111 int err;
112 112
113 if (sock->type != SOCK_RAW &&
114 sock->type != SOCK_DGRAM &&
115 !inet_ehash_secret)
116 build_ehash_secret();
117
118 /* Look for the requested type/protocol pair. */ 113 /* Look for the requested type/protocol pair. */
119lookup_protocol: 114lookup_protocol:
120 err = -ESOCKTNOSUPPORT; 115 err = -ESOCKTNOSUPPORT;
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 842d833dfc18..262e13c02ec2 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -23,6 +23,39 @@
23#include <net/secure_seq.h> 23#include <net/secure_seq.h>
24#include <net/ip.h> 24#include <net/ip.h>
25 25
26static unsigned int inet6_ehashfn(struct net *net,
27 const struct in6_addr *laddr,
28 const u16 lport,
29 const struct in6_addr *faddr,
30 const __be16 fport)
31{
32 static u32 inet6_ehash_secret __read_mostly;
33 static u32 ipv6_hash_secret __read_mostly;
34
35 u32 lhash, fhash;
36
37 net_get_random_once(&inet6_ehash_secret, sizeof(inet6_ehash_secret));
38 net_get_random_once(&ipv6_hash_secret, sizeof(ipv6_hash_secret));
39
40 lhash = (__force u32)laddr->s6_addr32[3];
41 fhash = __ipv6_addr_jhash(faddr, ipv6_hash_secret);
42
43 return __inet6_ehashfn(lhash, lport, fhash, fport,
44 inet6_ehash_secret + net_hash_mix(net));
45}
46
47static int inet6_sk_ehashfn(const struct sock *sk)
48{
49 const struct inet_sock *inet = inet_sk(sk);
50 const struct in6_addr *laddr = &sk->sk_v6_rcv_saddr;
51 const struct in6_addr *faddr = &sk->sk_v6_daddr;
52 const __u16 lport = inet->inet_num;
53 const __be16 fport = inet->inet_dport;
54 struct net *net = sock_net(sk);
55
56 return inet6_ehashfn(net, laddr, lport, faddr, fport);
57}
58
26int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) 59int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw)
27{ 60{
28 struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; 61 struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index d04d3f1dd9b7..535a3ad262f1 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -24,6 +24,8 @@
24#define COOKIEBITS 24 /* Upper bits store count */ 24#define COOKIEBITS 24 /* Upper bits store count */
25#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1) 25#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
26 26
27static u32 syncookie6_secret[2][16-4+SHA_DIGEST_WORDS];
28
27/* RFC 2460, Section 8.3: 29/* RFC 2460, Section 8.3:
28 * [ipv6 tcp] MSS must be computed as the maximum packet size minus 60 [..] 30 * [ipv6 tcp] MSS must be computed as the maximum packet size minus 60 [..]
29 * 31 *
@@ -61,14 +63,18 @@ static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS],
61static u32 cookie_hash(const struct in6_addr *saddr, const struct in6_addr *daddr, 63static u32 cookie_hash(const struct in6_addr *saddr, const struct in6_addr *daddr,
62 __be16 sport, __be16 dport, u32 count, int c) 64 __be16 sport, __be16 dport, u32 count, int c)
63{ 65{
64 __u32 *tmp = __get_cpu_var(ipv6_cookie_scratch); 66 __u32 *tmp;
67
68 net_get_random_once(syncookie6_secret, sizeof(syncookie6_secret));
69
70 tmp = __get_cpu_var(ipv6_cookie_scratch);
65 71
66 /* 72 /*
67 * we have 320 bits of information to hash, copy in the remaining 73 * we have 320 bits of information to hash, copy in the remaining
68 * 192 bits required for sha_transform, from the syncookie_secret 74 * 192 bits required for sha_transform, from the syncookie6_secret
69 * and overwrite the digest with the secret 75 * and overwrite the digest with the secret
70 */ 76 */
71 memcpy(tmp + 10, syncookie_secret[c], 44); 77 memcpy(tmp + 10, syncookie6_secret[c], 44);
72 memcpy(tmp, saddr, 16); 78 memcpy(tmp, saddr, 16);
73 memcpy(tmp + 4, daddr, 16); 79 memcpy(tmp + 4, daddr, 16);
74 tmp[8] = ((__force u32)sport << 16) + (__force u32)dport; 80 tmp[8] = ((__force u32)sport << 16) + (__force u32)dport;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index b496de19a341..44fc4e3d661f 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -53,6 +53,29 @@
53#include <trace/events/skb.h> 53#include <trace/events/skb.h>
54#include "udp_impl.h" 54#include "udp_impl.h"
55 55
56static unsigned int udp6_ehashfn(struct net *net,
57 const struct in6_addr *laddr,
58 const u16 lport,
59 const struct in6_addr *faddr,
60 const __be16 fport)
61{
62 static u32 udp6_ehash_secret __read_mostly;
63 static u32 udp_ipv6_hash_secret __read_mostly;
64
65 u32 lhash, fhash;
66
67 net_get_random_once(&udp6_ehash_secret,
68 sizeof(udp6_ehash_secret));
69 net_get_random_once(&udp_ipv6_hash_secret,
70 sizeof(udp_ipv6_hash_secret));
71
72 lhash = (__force u32)laddr->s6_addr32[3];
73 fhash = __ipv6_addr_jhash(faddr, udp_ipv6_hash_secret);
74
75 return __inet6_ehashfn(lhash, lport, fhash, fport,
76 udp_ipv6_hash_secret + net_hash_mix(net));
77}
78
56int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) 79int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
57{ 80{
58 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2); 81 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
@@ -214,8 +237,8 @@ begin:
214 badness = score; 237 badness = score;
215 reuseport = sk->sk_reuseport; 238 reuseport = sk->sk_reuseport;
216 if (reuseport) { 239 if (reuseport) {
217 hash = inet6_ehashfn(net, daddr, hnum, 240 hash = udp6_ehashfn(net, daddr, hnum,
218 saddr, sport); 241 saddr, sport);
219 matches = 1; 242 matches = 1;
220 } else if (score == SCORE2_MAX) 243 } else if (score == SCORE2_MAX)
221 goto exact_match; 244 goto exact_match;
@@ -295,8 +318,8 @@ begin:
295 badness = score; 318 badness = score;
296 reuseport = sk->sk_reuseport; 319 reuseport = sk->sk_reuseport;
297 if (reuseport) { 320 if (reuseport) {
298 hash = inet6_ehashfn(net, daddr, hnum, 321 hash = udp6_ehashfn(net, daddr, hnum,
299 saddr, sport); 322 saddr, sport);
300 matches = 1; 323 matches = 1;
301 } 324 }
302 } else if (score == badness && reuseport) { 325 } else if (score == badness && reuseport) {
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 642ad42c416b..378c3a6acf84 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -51,10 +51,16 @@ static struct kmem_cache *rds_conn_slab;
51 51
52static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr) 52static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr)
53{ 53{
54 static u32 rds_hash_secret __read_mostly;
55
56 unsigned long hash;
57
58 net_get_random_once(&rds_hash_secret, sizeof(rds_hash_secret));
59
54 /* Pass NULL, don't need struct net for hash */ 60 /* Pass NULL, don't need struct net for hash */
55 unsigned long hash = inet_ehashfn(NULL, 61 hash = __inet_ehashfn(be32_to_cpu(laddr), 0,
56 be32_to_cpu(laddr), 0, 62 be32_to_cpu(faddr), 0,
57 be32_to_cpu(faddr), 0); 63 rds_hash_secret);
58 return &rds_conn_hash[hash & RDS_CONNECTION_HASH_MASK]; 64 return &rds_conn_hash[hash & RDS_CONNECTION_HASH_MASK];
59} 65}
60 66