ipv6: split inet6_hash_frag for netfilter and initialize secrets with net_get_random_once
[cascardo/linux.git] / net / ipv6 / netfilter / nf_conntrack_reasm.c
index dffdc1a..4a25826 100644 (file)
@@ -144,12 +144,24 @@ static inline u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h)
        return 1 << (ipv6_get_dsfield(ipv6h) & INET_ECN_MASK);
 }
 
+static unsigned int nf_hash_frag(__be32 id, const struct in6_addr *saddr,
+                                const struct in6_addr *daddr)
+{
+       u32 c;
+
+       net_get_random_once(&nf_frags.rnd, sizeof(nf_frags.rnd));
+       c = jhash_3words(ipv6_addr_hash(saddr), ipv6_addr_hash(daddr),
+                        (__force u32)id, nf_frags.rnd);
+       return c & (INETFRAGS_HASHSZ - 1);
+}
+
+
 static unsigned int nf_hashfn(struct inet_frag_queue *q)
 {
        const struct frag_queue *nq;
 
        nq = container_of(q, struct frag_queue, q);
-       return inet6_hash_frag(nq->id, &nq->saddr, &nq->daddr, nf_frags.rnd);
+       return nf_hash_frag(nq->id, &nq->saddr, &nq->daddr);
 }
 
 static void nf_skb_free(struct sk_buff *skb)
@@ -185,7 +197,7 @@ static inline struct frag_queue *fq_find(struct net *net, __be32 id,
        arg.ecn = ecn;
 
        read_lock_bh(&nf_frags.lock);
-       hash = inet6_hash_frag(id, src, dst, nf_frags.rnd);
+       hash = nf_hash_frag(id, src, dst);
 
        q = inet_frag_find(&net->nf_frag.frags, &nf_frags, &arg, hash);
        local_bh_enable();