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 <edumazet@google.com> Cc: "David S. Miller" <davem@davemloft.net> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b23a002fc6
commit
1bbdceef1e
@ -204,10 +204,6 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to,
|
|||||||
|
|
||||||
int inet_sk_rebuild_header(struct sock *sk);
|
int inet_sk_rebuild_header(struct sock *sk);
|
||||||
|
|
||||||
extern u32 inet_ehash_secret;
|
|
||||||
extern u32 ipv6_hash_secret;
|
|
||||||
void build_ehash_secret(void);
|
|
||||||
|
|
||||||
static inline unsigned int __inet_ehashfn(const __be32 laddr,
|
static inline unsigned int __inet_ehashfn(const __be32 laddr,
|
||||||
const __u16 lport,
|
const __u16 lport,
|
||||||
const __be32 faddr,
|
const __be32 faddr,
|
||||||
|
@ -245,29 +245,6 @@ out:
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(inet_listen);
|
EXPORT_SYMBOL(inet_listen);
|
||||||
|
|
||||||
u32 inet_ehash_secret __read_mostly;
|
|
||||||
EXPORT_SYMBOL(inet_ehash_secret);
|
|
||||||
|
|
||||||
u32 ipv6_hash_secret __read_mostly;
|
|
||||||
EXPORT_SYMBOL(ipv6_hash_secret);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* inet_ehash_secret must be set exactly once, and to a non nul value
|
|
||||||
* ipv6_hash_secret must be set exactly once.
|
|
||||||
*/
|
|
||||||
void build_ehash_secret(void)
|
|
||||||
{
|
|
||||||
u32 rnd;
|
|
||||||
|
|
||||||
do {
|
|
||||||
get_random_bytes(&rnd, sizeof(rnd));
|
|
||||||
} while (rnd == 0);
|
|
||||||
|
|
||||||
if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0)
|
|
||||||
get_random_bytes(&ipv6_hash_secret, sizeof(ipv6_hash_secret));
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(build_ehash_secret);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create an inet socket.
|
* Create an inet socket.
|
||||||
*/
|
*/
|
||||||
@ -284,10 +261,6 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,
|
|||||||
int try_loading_module = 0;
|
int try_loading_module = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (unlikely(!inet_ehash_secret))
|
|
||||||
if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
|
|
||||||
build_ehash_secret();
|
|
||||||
|
|
||||||
sock->state = SS_UNCONNECTED;
|
sock->state = SS_UNCONNECTED;
|
||||||
|
|
||||||
/* Look for the requested type/protocol pair. */
|
/* Look for the requested type/protocol pair. */
|
||||||
|
@ -28,6 +28,10 @@ static unsigned int inet_ehashfn(struct net *net, const __be32 laddr,
|
|||||||
const __u16 lport, const __be32 faddr,
|
const __u16 lport, const __be32 faddr,
|
||||||
const __be16 fport)
|
const __be16 fport)
|
||||||
{
|
{
|
||||||
|
static u32 inet_ehash_secret __read_mostly;
|
||||||
|
|
||||||
|
net_get_random_once(&inet_ehash_secret, sizeof(inet_ehash_secret));
|
||||||
|
|
||||||
return __inet_ehashfn(laddr, lport, faddr, fport,
|
return __inet_ehashfn(laddr, lport, faddr, fport,
|
||||||
inet_ehash_secret + net_hash_mix(net));
|
inet_ehash_secret + net_hash_mix(net));
|
||||||
}
|
}
|
||||||
|
@ -411,8 +411,12 @@ static unsigned int udp_ehashfn(struct net *net, const __be32 laddr,
|
|||||||
const __u16 lport, const __be32 faddr,
|
const __u16 lport, const __be32 faddr,
|
||||||
const __be16 fport)
|
const __be16 fport)
|
||||||
{
|
{
|
||||||
|
static u32 udp_ehash_secret __read_mostly;
|
||||||
|
|
||||||
|
net_get_random_once(&udp_ehash_secret, sizeof(udp_ehash_secret));
|
||||||
|
|
||||||
return __inet_ehashfn(laddr, lport, faddr, fport,
|
return __inet_ehashfn(laddr, lport, faddr, fport,
|
||||||
inet_ehash_secret + net_hash_mix(net));
|
udp_ehash_secret + net_hash_mix(net));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,11 +110,6 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
|
|||||||
int try_loading_module = 0;
|
int try_loading_module = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (sock->type != SOCK_RAW &&
|
|
||||||
sock->type != SOCK_DGRAM &&
|
|
||||||
!inet_ehash_secret)
|
|
||||||
build_ehash_secret();
|
|
||||||
|
|
||||||
/* Look for the requested type/protocol pair. */
|
/* Look for the requested type/protocol pair. */
|
||||||
lookup_protocol:
|
lookup_protocol:
|
||||||
err = -ESOCKTNOSUPPORT;
|
err = -ESOCKTNOSUPPORT;
|
||||||
|
@ -29,10 +29,19 @@ static unsigned int inet6_ehashfn(struct net *net,
|
|||||||
const struct in6_addr *faddr,
|
const struct in6_addr *faddr,
|
||||||
const __be16 fport)
|
const __be16 fport)
|
||||||
{
|
{
|
||||||
const u32 lhash = (__force u32)laddr->s6_addr32[3];
|
static u32 inet6_ehash_secret __read_mostly;
|
||||||
const u32 fhash = __ipv6_addr_jhash(faddr, ipv6_hash_secret);
|
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,
|
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)
|
static int inet6_sk_ehashfn(const struct sock *sk)
|
||||||
|
@ -59,10 +59,21 @@ static unsigned int udp6_ehashfn(struct net *net,
|
|||||||
const struct in6_addr *faddr,
|
const struct in6_addr *faddr,
|
||||||
const __be16 fport)
|
const __be16 fport)
|
||||||
{
|
{
|
||||||
const u32 lhash = (__force u32)laddr->s6_addr32[3];
|
static u32 udp6_ehash_secret __read_mostly;
|
||||||
const u32 fhash = __ipv6_addr_jhash(faddr, ipv6_hash_secret);
|
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,
|
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)
|
int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
|
||||||
|
@ -51,10 +51,16 @@ static struct kmem_cache *rds_conn_slab;
|
|||||||
|
|
||||||
static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr)
|
static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr)
|
||||||
{
|
{
|
||||||
|
static u32 rds_hash_secret __read_mostly;
|
||||||
|
|
||||||
|
unsigned long hash;
|
||||||
|
|
||||||
|
net_get_random_once(&rds_hash_secret, sizeof(rds_hash_secret));
|
||||||
|
|
||||||
/* Pass NULL, don't need struct net for hash */
|
/* Pass NULL, don't need struct net for hash */
|
||||||
unsigned long hash = __inet_ehashfn(be32_to_cpu(laddr), 0,
|
hash = __inet_ehashfn(be32_to_cpu(laddr), 0,
|
||||||
be32_to_cpu(faddr), 0,
|
be32_to_cpu(faddr), 0,
|
||||||
inet_ehash_secret);
|
rds_hash_secret);
|
||||||
return &rds_conn_hash[hash & RDS_CONNECTION_HASH_MASK];
|
return &rds_conn_hash[hash & RDS_CONNECTION_HASH_MASK];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user