Commit b50026b5 authored by Hannes Frederic Sowa's avatar Hannes Frederic Sowa Committed by David S. Miller

ipv6: split inet6_ehashfn to hash functions per compilation unit

This patch splits the inet6_ehashfn into separate ones in
ipv6/inet6_hashtables.o and ipv6/udp.o to ease the introduction of
seperate secrets keys later.

Cc: Eric Dumazet <edumazet@google.com>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 65cd8033
...@@ -28,28 +28,14 @@ ...@@ -28,28 +28,14 @@
struct inet_hashinfo; struct inet_hashinfo;
static inline unsigned int inet6_ehashfn(struct net *net, static inline unsigned int __inet6_ehashfn(const u32 lhash,
const struct in6_addr *laddr, const u16 lport, const u16 lport,
const struct in6_addr *faddr, const __be16 fport) const u32 fhash,
const __be16 fport,
const u32 initval)
{ {
u32 ports = (((u32)lport) << 16) | (__force u32)fport; const u32 ports = (((u32)lport) << 16) | (__force u32)fport;
return jhash_3words(lhash, fhash, ports, initval);
return jhash_3words((__force u32)laddr->s6_addr32[3],
ipv6_addr_jhash(faddr),
ports,
inet_ehash_secret + net_hash_mix(net));
}
static inline int inet6_sk_ehashfn(const struct sock *sk)
{
const struct inet_sock *inet = inet_sk(sk);
const struct in6_addr *laddr = &sk->sk_v6_rcv_saddr;
const struct in6_addr *faddr = &sk->sk_v6_daddr;
const __u16 lport = inet->inet_num;
const __be16 fport = inet->inet_dport;
struct net *net = sock_net(sk);
return inet6_ehashfn(net, laddr, lport, faddr, fport);
} }
int __inet6_hash(struct sock *sk, struct inet_timewait_sock *twp); int __inet6_hash(struct sock *sk, struct inet_timewait_sock *twp);
......
...@@ -539,14 +539,14 @@ static inline u32 ipv6_addr_hash(const struct in6_addr *a) ...@@ -539,14 +539,14 @@ static inline u32 ipv6_addr_hash(const struct in6_addr *a)
} }
/* more secured version of ipv6_addr_hash() */ /* more secured version of ipv6_addr_hash() */
static inline u32 ipv6_addr_jhash(const struct in6_addr *a) static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 initval)
{ {
u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1]; u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1];
return jhash_3words(v, return jhash_3words(v,
(__force u32)a->s6_addr32[2], (__force u32)a->s6_addr32[2],
(__force u32)a->s6_addr32[3], (__force u32)a->s6_addr32[3],
ipv6_hash_secret); initval);
} }
static inline bool ipv6_addr_loopback(const struct in6_addr *a) static inline bool ipv6_addr_loopback(const struct in6_addr *a)
......
...@@ -23,6 +23,30 @@ ...@@ -23,6 +23,30 @@
#include <net/secure_seq.h> #include <net/secure_seq.h>
#include <net/ip.h> #include <net/ip.h>
static unsigned int inet6_ehashfn(struct net *net,
const struct in6_addr *laddr,
const u16 lport,
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);
return __inet6_ehashfn(lhash, lport, fhash, fport,
inet_ehash_secret + net_hash_mix(net));
}
static int inet6_sk_ehashfn(const struct sock *sk)
{
const struct inet_sock *inet = inet_sk(sk);
const struct in6_addr *laddr = &sk->sk_v6_rcv_saddr;
const struct in6_addr *faddr = &sk->sk_v6_daddr;
const __u16 lport = inet->inet_num;
const __be16 fport = inet->inet_dport;
struct net *net = sock_net(sk);
return inet6_ehashfn(net, laddr, lport, faddr, fport);
}
int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw)
{ {
struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;
......
...@@ -53,6 +53,18 @@ ...@@ -53,6 +53,18 @@
#include <trace/events/skb.h> #include <trace/events/skb.h>
#include "udp_impl.h" #include "udp_impl.h"
static unsigned int udp6_ehashfn(struct net *net,
const struct in6_addr *laddr,
const u16 lport,
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);
return __inet6_ehashfn(lhash, lport, fhash, fport,
inet_ehash_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)
{ {
const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2); const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
...@@ -214,7 +226,7 @@ static struct sock *udp6_lib_lookup2(struct net *net, ...@@ -214,7 +226,7 @@ static struct sock *udp6_lib_lookup2(struct net *net,
badness = score; badness = score;
reuseport = sk->sk_reuseport; reuseport = sk->sk_reuseport;
if (reuseport) { if (reuseport) {
hash = inet6_ehashfn(net, daddr, hnum, hash = udp6_ehashfn(net, daddr, hnum,
saddr, sport); saddr, sport);
matches = 1; matches = 1;
} else if (score == SCORE2_MAX) } else if (score == SCORE2_MAX)
...@@ -295,7 +307,7 @@ struct sock *__udp6_lib_lookup(struct net *net, ...@@ -295,7 +307,7 @@ struct sock *__udp6_lib_lookup(struct net *net,
badness = score; badness = score;
reuseport = sk->sk_reuseport; reuseport = sk->sk_reuseport;
if (reuseport) { if (reuseport) {
hash = inet6_ehashfn(net, daddr, hnum, hash = udp6_ehashfn(net, daddr, hnum,
saddr, sport); saddr, sport);
matches = 1; matches = 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment