Index: conf/files =================================================================== RCS file: /cvs/src/sys/conf/files,v retrieving revision 1.583 diff -u -p -r1.583 files --- conf/files 20 Oct 2014 00:38:50 -0000 1.583 +++ conf/files 4 Nov 2014 04:47:11 -0000 @@ -873,6 +873,7 @@ file crypto/hmac.c wlan | (softraid & file crypto/gmac.c (inet & ipsec) | crypto file crypto/key_wrap.c wlan file crypto/idgen.c inet6 | nfsclient | nfsserver +file crypto/siphash.c file netmpls/mpls_input.c mpls file netmpls/mpls_output.c mpls file netmpls/mpls_proto.c mpls Index: netinet/in_pcb.c =================================================================== RCS file: /cvs/src/sys/netinet/in_pcb.c,v retrieving revision 1.160 diff -u -p -r1.160 in_pcb.c --- netinet/in_pcb.c 14 Oct 2014 09:52:26 -0000 1.160 +++ netinet/in_pcb.c 4 Nov 2014 04:47:11 -0000 @@ -91,6 +91,7 @@ #include #include + #include #include @@ -121,17 +122,68 @@ int in_pcbresize (struct inpcbtable *, i #define INPCBHASH_LOADFACTOR(_x) (((_x) * 3) / 4) +struct inpcbhead *in_pcbhash(struct inpcbtable *, int, + const struct in_addr *, u_short, const struct in_addr *, u_short); +struct inpcbhead *in6_pcbhash(struct inpcbtable *, int, + const struct in6_addr *, u_short, const struct in6_addr *, u_short); +struct inpcbhead *in_pcblhash(struct inpcbtable *, int, u_short); + +struct inpcbhead * +in_pcbhash(struct inpcbtable *table, int rdom, + const struct in_addr *faddr, u_short fport, + const struct in_addr *laddr, u_short lport) +{ + SIPHASH_CTX ctx; + u_int32_t nrdom = htonl(rdom); + + SipHash24_Init(&ctx, &table->inpt_key); + SipHash24_Update(&ctx, &nrdom, sizeof(nrdom)); + SipHash24_Update(&ctx, faddr, sizeof(*faddr)); + SipHash24_Update(&ctx, &fport, sizeof(fport)); + SipHash24_Update(&ctx, laddr, sizeof(*laddr)); + SipHash24_Update(&ctx, &lport, sizeof(lport)); + + return (&table->inpt_hashtbl[SipHash24_End(&ctx) & table->inpt_hash]); +} + #define INPCBHASH(table, faddr, fport, laddr, lport, rdom) \ - &(table)->inpt_hashtbl[(ntohl((faddr)->s_addr) + \ - ntohs((fport)) + ntohs((lport)) + (rdom)) & (table->inpt_hash)] + in_pcbhash(table, rdom, faddr, fport, laddr, lport) + +struct inpcbhead * +in6_pcbhash(struct inpcbtable *table, int rdom, + const struct in6_addr *faddr, u_short fport, + const struct in6_addr *laddr, u_short lport) +{ + SIPHASH_CTX ctx; + u_int32_t nrdom = htonl(rdom); + + SipHash24_Init(&ctx, &table->inpt_key); + SipHash24_Update(&ctx, &nrdom, sizeof(nrdom)); + SipHash24_Update(&ctx, faddr, sizeof(*faddr)); + SipHash24_Update(&ctx, &fport, sizeof(fport)); + SipHash24_Update(&ctx, laddr, sizeof(*laddr)); + SipHash24_Update(&ctx, &lport, sizeof(lport)); + + return (&table->inpt_hashtbl[SipHash24_End(&ctx) & table->inpt_hash]); +} #define IN6PCBHASH(table, faddr, fport, laddr, lport, rdom) \ - &(table)->inpt_hashtbl[(ntohl((faddr)->s6_addr32[0] ^ \ - (faddr)->s6_addr32[3]) + ntohs((fport)) + ntohs((lport)) + (rdom)) & \ - (table->inpt_hash)] + in6_pcbhash(table, rdom, faddr, fport, laddr, lport) + +struct inpcbhead * +in_pcblhash(struct inpcbtable *table, int rdom, u_short lport) +{ + SIPHASH_CTX ctx; + u_int32_t nrdom = htonl(rdom); + + SipHash24_Init(&ctx, &table->inpt_key); + SipHash24_Update(&ctx, &nrdom, sizeof(nrdom)); + SipHash24_Update(&ctx, &lport, sizeof(lport)); + + return (&table->inpt_lhashtbl[SipHash24_End(&ctx) & table->inpt_lhash]); +} -#define INPCBLHASH(table, lport, rdom) \ - &(table)->inpt_lhashtbl[(ntohs((lport)) + (rdom)) & table->inpt_lhash] +#define INPCBLHASH(table, lport, rdom) in_pcblhash(table, rdom, lport) void in_pcbinit(struct inpcbtable *table, int hashsize) @@ -148,6 +200,7 @@ in_pcbinit(struct inpcbtable *table, int panic("in_pcbinit: hashinit failed for lport"); table->inpt_lastport = 0; table->inpt_count = 0; + arc4random_buf(&table->inpt_key, sizeof(table->inpt_key)); } /* @@ -914,6 +967,7 @@ in_pcbresize(struct inpcbtable *table, i table->inpt_lhashtbl = nlhashtbl; table->inpt_hash = nhash; table->inpt_lhash = nlhash; + arc4random_buf(&table->inpt_key, sizeof(table->inpt_key)); TAILQ_FOREACH_SAFE(inp0, &table->inpt_queue, inp_queue, inp1) { in_pcbrehash(inp0); Index: netinet/in_pcb.h =================================================================== RCS file: /cvs/src/sys/netinet/in_pcb.h,v retrieving revision 1.86 diff -u -p -r1.86 in_pcb.h --- netinet/in_pcb.h 12 Jul 2014 21:06:34 -0000 1.86 +++ netinet/in_pcb.h 4 Nov 2014 04:47:11 -0000 @@ -70,6 +70,8 @@ #include #include +#include + struct pf_state_key; union inpaddru { @@ -153,9 +155,12 @@ struct inpcb { int inp_divertfl; /* divert flags */ }; +LIST_HEAD(inpcbhead, inpcb); + struct inpcbtable { TAILQ_HEAD(inpthead, inpcb) inpt_queue; - LIST_HEAD(inpcbhead, inpcb) *inpt_hashtbl, *inpt_lhashtbl; + struct inpcbhead *inpt_hashtbl, *inpt_lhashtbl; + SIPHASH_KEY inpt_key; u_long inpt_hash, inpt_lhash; u_int16_t inpt_lastport; int inpt_count;