]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/ipv6/inet6_hashtables.c
Merge remote-tracking branch 'input/next'
[karo-tx-linux.git] / net / ipv6 / inet6_hashtables.c
index 842d833dfc186122a167d985763d8e637c11018e..262e13c02ec27dea15154d9b4af5fd413dd1c504 100644 (file)
 #include <net/secure_seq.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)
+{
+       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,
+                              inet6_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)
 {
        struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;