From 1bbdceef1e535add893bf71d7b7ab102e4eb69eb Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Sat, 19 Oct 2013 21:48:57 +0200 Subject: inet: convert inet_ehash_secret and ipv6_hash_secret to net_get_random_once Initialize the ehash and ipv6_hash_secrets with net_get_random_once. Each compilation unit gets its own secret now: ipv4/inet_hashtables.o ipv4/udp.o ipv6/inet6_hashtables.o ipv6/udp.o rds/connection.o The functions still get inlined into the hashing functions. In the fast path we have at most two (needed in ipv6) if (unlikely(...)). Cc: Eric Dumazet Cc: "David S. Miller" Signed-off-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- net/ipv6/af_inet6.c | 5 ----- net/ipv6/inet6_hashtables.c | 15 ++++++++++++--- net/ipv6/udp.c | 17 ++++++++++++++--- 3 files changed, 26 insertions(+), 11 deletions(-) (limited to 'net/ipv6') 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, int try_loading_module = 0; int err; - if (sock->type != SOCK_RAW && - sock->type != SOCK_DGRAM && - !inet_ehash_secret) - build_ehash_secret(); - /* Look for the requested type/protocol pair. */ lookup_protocol: 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, const struct in6_addr *faddr, const __be16 fport) { - const u32 lhash = (__force u32)laddr->s6_addr32[3]; - const u32 fhash = __ipv6_addr_jhash(faddr, ipv6_hash_secret); + static u32 inet6_ehash_secret __read_mostly; + static u32 ipv6_hash_secret __read_mostly; + + u32 lhash, fhash; + + net_get_random_once(&inet6_ehash_secret, sizeof(inet6_ehash_secret)); + net_get_random_once(&ipv6_hash_secret, sizeof(ipv6_hash_secret)); + + lhash = (__force u32)laddr->s6_addr32[3]; + fhash = __ipv6_addr_jhash(faddr, ipv6_hash_secret); + return __inet6_ehashfn(lhash, lport, fhash, fport, - inet_ehash_secret + net_hash_mix(net)); + inet6_ehash_secret + net_hash_mix(net)); } 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, const struct in6_addr *faddr, const __be16 fport) { - const u32 lhash = (__force u32)laddr->s6_addr32[3]; - const u32 fhash = __ipv6_addr_jhash(faddr, ipv6_hash_secret); + static u32 udp6_ehash_secret __read_mostly; + static u32 udp_ipv6_hash_secret __read_mostly; + + u32 lhash, fhash; + + net_get_random_once(&udp6_ehash_secret, + sizeof(udp6_ehash_secret)); + net_get_random_once(&udp_ipv6_hash_secret, + sizeof(udp_ipv6_hash_secret)); + + lhash = (__force u32)laddr->s6_addr32[3]; + fhash = __ipv6_addr_jhash(faddr, udp_ipv6_hash_secret); + return __inet6_ehashfn(lhash, lport, fhash, fport, - inet_ehash_secret + net_hash_mix(net)); + udp_ipv6_hash_secret + net_hash_mix(net)); } int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) -- cgit v1.2.3