Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Sep 2012 04:50:21 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r240125 - projects/pf/head/sys/contrib/pf/net
Message-ID:  <201209050450.q854oL7J075975@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Wed Sep  5 04:50:20 2012
New Revision: 240125
URL: http://svn.freebsd.org/changeset/base/240125

Log:
  Use Jenkins's hash with random seed for pf keys.

Modified:
  projects/pf/head/sys/contrib/pf/net/pf.c

Modified: projects/pf/head/sys/contrib/pf/net/pf.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf.c	Wed Sep  5 02:26:13 2012	(r240124)
+++ projects/pf/head/sys/contrib/pf/net/pf.c	Wed Sep  5 04:50:20 2012	(r240125)
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mbuf.h>
 #include <sys/interrupt.h>
 #include <sys/filio.h>
+#include <sys/hash.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/kernel.h>
@@ -395,57 +396,17 @@ SYSCTL_VNET_UINT(_net_pf, OID_AUTO, sour
 
 VNET_DEFINE(void *, pf_swi_cookie);
 
-/*
- * Hash function shamelessly taken from ng_netflow(4), trusting
- * mav@ and melifaro@ data on its decent distribution.
- */
-static __inline u_int
+VNET_DEFINE(uint32_t, pf_hashseed);
+#define	V_pf_hashseed	VNET(pf_hashseed)
+
+static __inline uint32_t
 pf_hashkey(struct pf_state_key *sk)
 {
-	u_int h;
+	uint32_t h;
 
-#define	FULL_HASH(a1, a2, p1, p2)	\
-	(((a1) ^ ((a1) >> 16) ^		\
-	htons((a2) ^ ((a2) >> 16))) ^	\
-	(p1) ^ htons(p2))
- 
-#define	ADDR_HASH(a1, a2)		\
-	((a1) ^ ((a1) >> 16) ^		\
-	htons((a2) ^ ((a2) >> 16)))
-
-	switch (sk->af) {
-	case AF_INET:
-		switch (sk->proto) {
-		case IPPROTO_TCP:
-		case IPPROTO_UDP:
-			h = FULL_HASH(sk->addr[0].v4.s_addr,
-			    sk->addr[1].v4.s_addr, sk->port[0], sk->port[1]);
-			break;
-		default:
-			h = ADDR_HASH(sk->addr[0].v4.s_addr,
-			    sk->addr[1].v4.s_addr);
-			break;
-		}
-		break;
-	case AF_INET6:
-		switch (sk->proto) {
-		case IPPROTO_TCP:
-		case IPPROTO_UDP:
-			h = FULL_HASH(sk->addr[0].v6.__u6_addr.__u6_addr32[3],
-			    sk->addr[1].v6.__u6_addr.__u6_addr32[3],
-			    sk->port[0], sk->port[1]);
-			break;
-		default:
-			h = ADDR_HASH(sk->addr[0].v6.__u6_addr.__u6_addr32[3],
-			    sk->addr[1].v6.__u6_addr.__u6_addr32[3]);
-			break;
-		}
-		break;
-	default:
-		panic("%s: unknown address family %u", __func__, sk->af);
-	}
-#undef FULL_HASH
-#undef ADDR_HASH
+	h = jenkins_hash32((uint32_t *)sk,
+	    sizeof(struct pf_state_key_cmp)/sizeof(uint32_t),
+	    V_pf_hashseed);
 
 	return (h & V_pf_hashmask);
 }
@@ -733,6 +694,8 @@ pf_initialize()
 	if (V_pf_srchashsize == 0 || !powerof2(V_pf_srchashsize))
 		V_pf_srchashsize = PF_HASHSIZ / 4;
 
+	V_pf_hashseed = arc4random();
+
 	/* States and state keys storage. */
 	V_pf_state_z = uma_zcreate("pf states", sizeof(struct pf_state),
 	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209050450.q854oL7J075975>