Skip to content

Commit eaf9e71

Browse files
Florian Westphalummakynes
Florian Westphal
authored andcommitted
netfilter: conntrack: don't fold port numbers into addresses before hashing
Originally this used jhash2() over tuple and folded the zone id, the pernet hash value, destination port and l4 protocol number into the 32bit seed value. When the switch to siphash was done, I used an on-stack temporary buffer to build a suitable key to be hashed via siphash(). But this showed up as performance regression, so I got rid of the temporary copy and collected to-be-hashed data in 4 u64 variables. This makes it easy to build tuples that produce the same hash, which isn't desirable even though chain lengths are limited. Switch back to plain siphash, but just like with jhash2(), take advantage of the fact that most of to-be-hashed data is already in a suitable order. Use an empty struct as annotation in 'struct nf_conntrack_tuple' to mark last member that can be used as hash input. The only remaining data that isn't present in the tuple structure are the zone identifier and the pernet hash: fold those into the key. Fixes: d2c806a ("netfilter: conntrack: use siphash_4u64") Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 6eef7a2 commit eaf9e71

File tree

2 files changed

+10
-13
lines changed

2 files changed

+10
-13
lines changed

include/net/netfilter/nf_conntrack_tuple.h

+3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ struct nf_conntrack_tuple {
6767
/* The protocol. */
6868
u_int8_t protonum;
6969

70+
/* The direction must be ignored for the tuplehash */
71+
struct { } __nfct_hash_offsetend;
72+
7073
/* The direction (for tuplehash) */
7174
u_int8_t dir;
7275
} dst;

net/netfilter/nf_conntrack_core.c

+7-13
Original file line numberDiff line numberDiff line change
@@ -211,24 +211,18 @@ static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple,
211211
unsigned int zoneid,
212212
const struct net *net)
213213
{
214-
u64 a, b, c, d;
214+
siphash_key_t key;
215215

216216
get_random_once(&nf_conntrack_hash_rnd, sizeof(nf_conntrack_hash_rnd));
217217

218-
/* The direction must be ignored, handle usable tuplehash members manually */
219-
a = (u64)tuple->src.u3.all[0] << 32 | tuple->src.u3.all[3];
220-
b = (u64)tuple->dst.u3.all[0] << 32 | tuple->dst.u3.all[3];
218+
key = nf_conntrack_hash_rnd;
221219

222-
c = (__force u64)tuple->src.u.all << 32 | (__force u64)tuple->dst.u.all << 16;
223-
c |= tuple->dst.protonum;
220+
key.key[0] ^= zoneid;
221+
key.key[1] ^= net_hash_mix(net);
224222

225-
d = (u64)zoneid << 32 | net_hash_mix(net);
226-
227-
/* IPv4: u3.all[1,2,3] == 0 */
228-
c ^= (u64)tuple->src.u3.all[1] << 32 | tuple->src.u3.all[2];
229-
d += (u64)tuple->dst.u3.all[1] << 32 | tuple->dst.u3.all[2];
230-
231-
return (u32)siphash_4u64(a, b, c, d, &nf_conntrack_hash_rnd);
223+
return siphash((void *)tuple,
224+
offsetofend(struct nf_conntrack_tuple, dst.__nfct_hash_offsetend),
225+
&key);
232226
}
233227

234228
static u32 scale_hash(u32 hash)

0 commit comments

Comments
 (0)