diff options
-rw-r--r-- | include/net/inet_sock.h | 4 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 27 | ||||
-rw-r--r-- | net/ipv4/inet_hashtables.c | 4 | ||||
-rw-r--r-- | net/ipv4/udp.c | 6 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 5 | ||||
-rw-r--r-- | net/ipv6/inet6_hashtables.c | 15 | ||||
-rw-r--r-- | net/ipv6/udp.c | 17 | ||||
-rw-r--r-- | net/rds/connection.c | 12 |
8 files changed, 44 insertions, 46 deletions
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 7a6c7f80a8fd..1833c3f389ee 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h | |||
@@ -204,10 +204,6 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to, | |||
204 | 204 | ||
205 | int inet_sk_rebuild_header(struct sock *sk); | 205 | int inet_sk_rebuild_header(struct sock *sk); |
206 | 206 | ||
207 | extern u32 inet_ehash_secret; | ||
208 | extern u32 ipv6_hash_secret; | ||
209 | void build_ehash_secret(void); | ||
210 | |||
211 | static inline unsigned int __inet_ehashfn(const __be32 laddr, | 207 | static inline unsigned int __inet_ehashfn(const __be32 laddr, |
212 | const __u16 lport, | 208 | const __u16 lport, |
213 | const __be32 faddr, | 209 | const __be32 faddr, |
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 | } |
246 | EXPORT_SYMBOL(inet_listen); | 246 | EXPORT_SYMBOL(inet_listen); |
247 | 247 | ||
248 | u32 inet_ehash_secret __read_mostly; | ||
249 | EXPORT_SYMBOL(inet_ehash_secret); | ||
250 | |||
251 | u32 ipv6_hash_secret __read_mostly; | ||
252 | EXPORT_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 | */ | ||
258 | void 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 | } | ||
269 | EXPORT_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 18aa668d0cc9..8b9cf279450d 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -28,6 +28,10 @@ static unsigned int inet_ehashfn(struct net *net, const __be32 laddr, | |||
28 | const __u16 lport, const __be32 faddr, | 28 | const __u16 lport, const __be32 faddr, |
29 | const __be16 fport) | 29 | const __be16 fport) |
30 | { | 30 | { |
31 | static u32 inet_ehash_secret __read_mostly; | ||
32 | |||
33 | net_get_random_once(&inet_ehash_secret, sizeof(inet_ehash_secret)); | ||
34 | |||
31 | return __inet_ehashfn(laddr, lport, faddr, fport, | 35 | return __inet_ehashfn(laddr, lport, faddr, fport, |
32 | inet_ehash_secret + net_hash_mix(net)); | 36 | inet_ehash_secret + net_hash_mix(net)); |
33 | } | 37 | } |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index b4437c7db6ce..89909dd730dd 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -411,8 +411,12 @@ static unsigned int udp_ehashfn(struct net *net, const __be32 laddr, | |||
411 | const __u16 lport, const __be32 faddr, | 411 | const __u16 lport, const __be32 faddr, |
412 | const __be16 fport) | 412 | const __be16 fport) |
413 | { | 413 | { |
414 | static u32 udp_ehash_secret __read_mostly; | ||
415 | |||
416 | net_get_random_once(&udp_ehash_secret, sizeof(udp_ehash_secret)); | ||
417 | |||
414 | return __inet_ehashfn(laddr, lport, faddr, fport, | 418 | return __inet_ehashfn(laddr, lport, faddr, fport, |
415 | inet_ehash_secret + net_hash_mix(net)); | 419 | udp_ehash_secret + net_hash_mix(net)); |
416 | } | 420 | } |
417 | 421 | ||
418 | 422 | ||
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. */ |
119 | lookup_protocol: | 114 | lookup_protocol: |
120 | err = -ESOCKTNOSUPPORT; | 115 | err = -ESOCKTNOSUPPORT; |
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index fa7dd3856c55..262e13c02ec2 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c | |||
@@ -29,10 +29,19 @@ static unsigned int inet6_ehashfn(struct net *net, | |||
29 | const struct in6_addr *faddr, | 29 | const struct in6_addr *faddr, |
30 | const __be16 fport) | 30 | const __be16 fport) |
31 | { | 31 | { |
32 | const u32 lhash = (__force u32)laddr->s6_addr32[3]; | 32 | static u32 inet6_ehash_secret __read_mostly; |
33 | const u32 fhash = __ipv6_addr_jhash(faddr, ipv6_hash_secret); | 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 | |||
34 | return __inet6_ehashfn(lhash, lport, fhash, fport, | 43 | return __inet6_ehashfn(lhash, lport, fhash, fport, |
35 | inet_ehash_secret + net_hash_mix(net)); | 44 | inet6_ehash_secret + net_hash_mix(net)); |
36 | } | 45 | } |
37 | 46 | ||
38 | static int inet6_sk_ehashfn(const struct sock *sk) | 47 | static int inet6_sk_ehashfn(const struct sock *sk) |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 324bd36c23bc..44fc4e3d661f 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -59,10 +59,21 @@ static unsigned int udp6_ehashfn(struct net *net, | |||
59 | const struct in6_addr *faddr, | 59 | const struct in6_addr *faddr, |
60 | const __be16 fport) | 60 | const __be16 fport) |
61 | { | 61 | { |
62 | const u32 lhash = (__force u32)laddr->s6_addr32[3]; | 62 | static u32 udp6_ehash_secret __read_mostly; |
63 | const u32 fhash = __ipv6_addr_jhash(faddr, ipv6_hash_secret); | 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 | |||
64 | return __inet6_ehashfn(lhash, lport, fhash, fport, | 75 | return __inet6_ehashfn(lhash, lport, fhash, fport, |
65 | inet_ehash_secret + net_hash_mix(net)); | 76 | udp_ipv6_hash_secret + net_hash_mix(net)); |
66 | } | 77 | } |
67 | 78 | ||
68 | int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) | 79 | int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) |
diff --git a/net/rds/connection.c b/net/rds/connection.c index 45e23660437a..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 | ||
52 | static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr) | 52 | static 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(be32_to_cpu(laddr), 0, | 61 | hash = __inet_ehashfn(be32_to_cpu(laddr), 0, |
56 | be32_to_cpu(faddr), 0, | 62 | be32_to_cpu(faddr), 0, |
57 | inet_ehash_secret); | 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 | ||