i have no idea how to test this.
tests? oks?
Index: ip_mroute.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_mroute.c,v
retrieving revision 1.71
diff -u -p -r1.71 ip_mroute.c
--- ip_mroute.c 30 Sep 2014 12:54:22 -0000 1.71
+++ ip_mroute.c 15 Nov 2014 11:18:29 -0000
@@ -93,6 +93,9 @@
#include <sys/stdarg.h>
+#include <dev/rndvar.h>
+#include <crypto/siphash.h>
+
#define IP_MULTICASTOPTS 0
#define M_PULLUP(m, len)
\
do { \
@@ -110,11 +113,12 @@ int ip_mrtproto = IGMP_DVMRP; /* for
#define NO_RTE_FOUND 0x1
#define RTE_FOUND 0x2
-#define MFCHASH(a, g)
\
- ((((a).s_addr >> 20) ^ ((a).s_addr >> 10) ^ (a).s_addr ^ \
- ((g).s_addr >> 20) ^ ((g).s_addr >> 10) ^ (g).s_addr) & mfchash)
+u_int32_t _mfchash(struct in_addr, struct in_addr);
+
+#define MFCHASH(a, g) _mfchash((a), (g))
LIST_HEAD(mfchashhdr, mfc) *mfchashtbl;
u_long mfchash;
+SIPHASH_KEY mfchashkey;
u_char nexpire[MFCTBLSIZ];
struct vif viftable[MAXVIFS];
@@ -281,8 +285,10 @@ static struct mfc *
mfc_find(struct in_addr *o, struct in_addr *g)
{
struct mfc *rt;
+ u_int32_t hash;
- LIST_FOREACH(rt, &mfchashtbl[MFCHASH(*o, *g)], mfc_hash) {
+ hash = MFCHASH(*o, *g);
+ LIST_FOREACH(rt, &mfchashtbl[hash], mfc_hash) {
if (in_hosteq(rt->mfc_origin, *o) &&
in_hosteq(rt->mfc_mcastgrp, *g) &&
(rt->mfc_stall == NULL))
@@ -498,6 +504,7 @@ ip_mrouter_init(struct socket *so, struc
ip_mrouter = so;
mfchashtbl = hashinit(MFCTBLSIZ, M_MRTABLE, M_WAITOK, &mfchash);
+ arc4random_buf(&mfchashkey, sizeof(mfchashkey));
memset(nexpire, 0, sizeof(nexpire));
pim_assert = 0;
@@ -509,6 +516,18 @@ ip_mrouter_init(struct socket *so, struc
log(LOG_DEBUG, "ip_mrouter_init\n");
return (0);
+}
+
+u_int32_t
+_mfchash(struct in_addr o, struct in_addr g)
+{
+ SIPHASH_CTX ctx;
+
+ SipHash24_Init(&ctx, &mfchashkey);
+ SipHash24_Update(&ctx, &o.s_addr, sizeof(o.s_addr));
+ SipHash24_Update(&ctx, &g.s_addr, sizeof(g.s_addr));
+
+ return (SipHash24_End(&ctx) & mfchash);
}
/*