summaryrefslogtreecommitdiff
path: root/sys/net/pf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/pf.c')
-rw-r--r--sys/net/pf.c89
1 files changed, 62 insertions, 27 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 4233968cb18..416235f14fb 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.263 2002/11/24 22:45:48 mcbride Exp $ */
+/* $OpenBSD: pf.c,v 1.264 2002/11/28 12:07:37 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -46,7 +46,6 @@
#include <sys/kernel.h>
#include <sys/time.h>
#include <sys/pool.h>
-#include <sys/md5k.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -227,6 +226,8 @@ void pf_poolmask(struct pf_addr *, struct pf_addr*,
struct pf_addr *, struct pf_addr *, u_int8_t);
void pf_addr_inc(struct pf_addr *, sa_family_t);
#endif /* INET6 */
+void pf_hash(struct pf_addr *, struct pf_addr *,
+ struct pf_poolhashkey *, sa_family_t);
int pf_map_addr(u_int8_t, struct pf_pool *,
struct pf_addr *, struct pf_addr *,
struct pf_addr *);
@@ -1282,11 +1283,67 @@ pf_addr_inc(struct pf_addr *addr, u_int8_t af)
}
#endif /* INET6 */
+#define mix(a,b,c) \
+ do { \
+ a -= b; a -= c; a ^= (c >> 13); \
+ b -= c; b -= a; b ^= (a << 8); \
+ c -= a; c -= b; c ^= (b >> 13); \
+ a -= b; a -= c; a ^= (c >> 12); \
+ b -= c; b -= a; b ^= (a << 16); \
+ c -= a; c -= b; c ^= (b >> 5); \
+ a -= b; a -= c; a ^= (c >> 3); \
+ b -= c; b -= a; b ^= (a << 10); \
+ c -= a; c -= b; c ^= (b >> 15); \
+ } while(0)
+
+/*
+ * hash function based on bridge_hash in if_bridge.c
+ */
+void
+pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
+ struct pf_poolhashkey *key, sa_family_t af)
+{
+ u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0];
+
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ a += inaddr->addr32[0];
+ b += key->key32[1];
+ mix(a, b, c);
+ hash->addr32[0] = c + key->key32[2];
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ a += inaddr->addr32[0];
+ b += inaddr->addr32[2];
+ mix(a, b, c);
+ hash->addr32[0] = c;
+ a += inaddr->addr32[1];
+ b += inaddr->addr32[3];
+ c += key->key32[1];
+ mix(a, b, c);
+ hash->addr32[1] = c;
+ a += inaddr->addr32[2];
+ b += inaddr->addr32[1];
+ c += key->key32[2];
+ mix(a, b, c);
+ hash->addr32[2] = c;
+ a += inaddr->addr32[3];
+ b += inaddr->addr32[0];
+ c += key->key32[3];
+ mix(a, b, c);
+ hash->addr32[3] = c;
+ break;
+#endif /* INET6 */
+ }
+}
+
int
pf_map_addr(u_int8_t af, struct pf_pool *rpool, struct pf_addr *saddr,
struct pf_addr *naddr, struct pf_addr *init_addr)
{
- MD5_CTX context;
unsigned char hash[16];
struct pf_pooladdr *cur = rpool->cur;
struct pf_addr *raddr = &rpool->cur->addr.addr;
@@ -1339,28 +1396,7 @@ pf_map_addr(u_int8_t af, struct pf_pool *rpool, struct pf_addr *saddr,
}
break;
case PF_POOL_SRCHASH:
- case PF_POOL_SRCKEYHASH:
- bzero(&context, sizeof(context));
- MD5Init(&context);
- switch (af) {
-#ifdef INET
- case AF_INET:
- MD5Update(&context, (unsigned char *)&saddr->v4,
- sizeof(saddr->v4));
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- MD5Update(&context, (unsigned char *)&saddr->v6,
- sizeof(saddr->v6));
- break;
-#endif /* INET6 */
- }
- if ((rpool->opts & PF_POOL_TYPEMASK) ==
- PF_POOL_SRCKEYHASH)
- MD5Update(&context, (unsigned char *)&rpool->key,
- sizeof(rpool->key));
- MD5Final(hash, &context);
+ pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
break;
case PF_POOL_ROUNDROBIN:
@@ -1383,7 +1419,7 @@ pf_map_addr(u_int8_t af, struct pf_pool *rpool, struct pf_addr *saddr,
printf("pf_map_addr: selected address:");
pf_print_host(naddr, 0, af);
printf("\n");
- }
+ }
return (0);
}
@@ -1473,7 +1509,6 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_pool *rpool,
break;
case PF_POOL_NONE:
case PF_POOL_SRCHASH:
- case PF_POOL_SRCKEYHASH:
case PF_POOL_BITMASK:
default:
return (1);