Trunk load balancing uses the hash32 functions from hash.h. SipHash is
probably better.
The LB_MAXKEYS define appears unused. I deleted it.
Index: if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.181
diff -u -p -r1.181 if_ethersubr.c
--- if_ethersubr.c 1 Dec 2014 17:46:56 -0000 1.181
+++ if_ethersubr.c 3 Dec 2014 04:06:43 -0000
@@ -87,6 +87,7 @@ didn't get a copy, you may request one f
#include <sys/syslog.h>
#include <sys/timeout.h>
+#include <crypto/siphash.h> /* required by if_trunk.h */
#include <net/if.h>
#include <net/netisr.h>
Index: if_trunk.c
===================================================================
RCS file: /cvs/src/sys/net/if_trunk.c,v
retrieving revision 1.92
diff -u -p -r1.92 if_trunk.c
--- if_trunk.c 1 Dec 2014 15:06:54 -0000 1.92
+++ if_trunk.c 3 Dec 2014 04:06:10 -0000
@@ -28,7 +28,8 @@
#include <sys/sockio.h>
#include <sys/systm.h>
#include <sys/timeout.h>
-#include <sys/hash.h>
+
+#include <crypto/siphash.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -969,7 +970,7 @@ trunk_enqueue(struct ifnet *ifp, struct
}
u_int32_t
-trunk_hashmbuf(struct mbuf *m, u_int32_t key)
+trunk_hashmbuf(struct mbuf *m, SIPHASH_KEY *key)
{
u_int16_t etype, ether_vtag;
u_int32_t p = 0;
@@ -983,25 +984,27 @@ trunk_hashmbuf(struct mbuf *m, u_int32_t
u_int32_t flow;
struct ip6_hdr *ip6, ip6buf;
#endif
+ SIPHASH_CTX ctx;
+ SipHash24_Init(&ctx, key);
off = sizeof(*eh);
if (m->m_len < off)
- return (p);
+ goto done;
eh = mtod(m, struct ether_header *);
etype = ntohs(eh->ether_type);
- p = hash32_buf(&eh->ether_shost, ETHER_ADDR_LEN, key);
- p = hash32_buf(&eh->ether_dhost, ETHER_ADDR_LEN, p);
+ SipHash24_Update(&ctx, &eh->ether_shost, ETHER_ADDR_LEN);
+ SipHash24_Update(&ctx, &eh->ether_dhost, ETHER_ADDR_LEN);
/* Special handling for encapsulating VLAN frames */
if (m->m_flags & M_VLANTAG) {
ether_vtag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
- p = hash32_buf(ðer_vtag, sizeof(ether_vtag), p);
+ SipHash24_Update(&ctx, ðer_vtag, sizeof(ether_vtag));
} else if (etype == ETHERTYPE_VLAN) {
if ((vlan = (u_int16_t *)
trunk_gethdr(m, off, EVL_ENCAPLEN, &vlanbuf)) == NULL)
return (p);
ether_vtag = EVL_VLANOFTAG(*vlan);
- p = hash32_buf(ðer_vtag, sizeof(ether_vtag), p);
+ SipHash24_Update(&ctx, ðer_vtag, sizeof(ether_vtag));
etype = ntohs(vlan[1]);
off += EVL_ENCAPLEN;
}
@@ -1012,8 +1015,8 @@ trunk_hashmbuf(struct mbuf *m, u_int32_t
if ((ip = (struct ip *)
trunk_gethdr(m, off, sizeof(*ip), &ipbuf)) == NULL)
return (p);
- p = hash32_buf(&ip->ip_src, sizeof(struct in_addr), p);
- p = hash32_buf(&ip->ip_dst, sizeof(struct in_addr), p);
+ SipHash24_Update(&ctx, &ip->ip_src, sizeof(struct in_addr));
+ SipHash24_Update(&ctx, &ip->ip_dst, sizeof(struct in_addr));
break;
#endif
#ifdef INET6
@@ -1021,15 +1024,16 @@ trunk_hashmbuf(struct mbuf *m, u_int32_t
if ((ip6 = (struct ip6_hdr *)
trunk_gethdr(m, off, sizeof(*ip6), &ip6buf)) == NULL)
return (p);
- p = hash32_buf(&ip6->ip6_src, sizeof(struct in6_addr), p);
- p = hash32_buf(&ip6->ip6_dst, sizeof(struct in6_addr), p);
+ SipHash24_Update(&ctx, &ip6->ip6_src, sizeof(struct in6_addr));
+ SipHash24_Update(&ctx, &ip6->ip6_dst, sizeof(struct in6_addr));
flow = ip6->ip6_flow & IPV6_FLOWLABEL_MASK;
- p = hash32_buf(&flow, sizeof(flow), p); /* IPv6 flow label */
+ SipHash24_Update(&ctx, &flow, sizeof(flow)); /* IPv6 flow label
*/
break;
#endif
}
- return (p);
+done:
+ return SipHash24_End(&ctx);
}
void
@@ -1405,7 +1409,7 @@ trunk_lb_attach(struct trunk_softc *tr)
tr->tr_init = NULL;
tr->tr_stop = NULL;
- lb->lb_key = arc4random();
+ arc4random_buf(&lb->lb_key, sizeof(lb->lb_key));
tr->tr_psc = (caddr_t)lb;
return (0);
@@ -1463,7 +1467,7 @@ trunk_lb_start(struct trunk_softc *tr, s
struct trunk_port *tp = NULL;
u_int32_t p = 0;
- p = trunk_hashmbuf(m, lb->lb_key);
+ p = trunk_hashmbuf(m, &lb->lb_key);
p %= tr->tr_count;
tp = lb->lb_ports[p];
Index: if_trunk.h
===================================================================
RCS file: /cvs/src/sys/net/if_trunk.h,v
retrieving revision 1.18
diff -u -p -r1.18 if_trunk.h
--- if_trunk.h 18 Nov 2013 09:16:30 -0000 1.18
+++ if_trunk.h 3 Dec 2014 04:04:42 -0000
@@ -214,16 +214,15 @@ struct trunk_softc {
#define IFCAP_TRUNK_FULLDUPLEX 0x00010000 /* full duplex with >1 ports */
/* Private data used by the loadbalancing protocol */
-#define TRUNK_LB_MAXKEYS 8
struct trunk_lb {
- u_int32_t lb_key;
+ SIPHASH_KEY lb_key;
struct trunk_port *lb_ports[TRUNK_MAX_PORTS];
};
int trunk_input(struct ifnet *, struct ether_header *,
struct mbuf *);
int trunk_enqueue(struct ifnet *, struct mbuf *);
-u_int32_t trunk_hashmbuf(struct mbuf *, u_int32_t);
+u_int32_t trunk_hashmbuf(struct mbuf *, SIPHASH_KEY *);
#endif /* _KERNEL */
#endif /* _NET_TRUNK_H */
Index: trunklacp.c
===================================================================
RCS file: /cvs/src/sys/net/trunklacp.c,v
retrieving revision 1.17
diff -u -p -r1.17 trunklacp.c
--- trunklacp.c 23 Nov 2014 07:39:02 -0000 1.17
+++ trunklacp.c 3 Dec 2014 04:05:54 -0000
@@ -41,6 +41,8 @@
#include <sys/queue.h>
#include <sys/timeout.h>
+#include <crypto/siphash.h>
+
#include <net/if.h>
#include <net/if_dl.h>
#include <net/ethertypes.h>
@@ -732,7 +734,7 @@ lacp_attach(struct trunk_softc *sc)
sc->tr_psc = (caddr_t)lsc;
lsc->lsc_softc = sc;
- lsc->lsc_hashkey = arc4random();
+ arc4random_buf(&lsc->lsc_hashkey, sizeof(lsc->lsc_hashkey));
lsc->lsc_active_aggregator = NULL;
TAILQ_INIT(&lsc->lsc_aggregators);
LIST_INIT(&lsc->lsc_ports);
@@ -799,7 +801,7 @@ lacp_select_tx_port(struct trunk_softc *
return (NULL);
}
- hash = trunk_hashmbuf(m, lsc->lsc_hashkey);
+ hash = trunk_hashmbuf(m, &lsc->lsc_hashkey);
hash %= pm->pm_count;
lp = pm->pm_map[hash];
Index: trunklacp.h
===================================================================
RCS file: /cvs/src/sys/net/trunklacp.h,v
retrieving revision 1.7
diff -u -p -r1.7 trunklacp.h
--- trunklacp.h 24 Oct 2013 18:50:16 -0000 1.7
+++ trunklacp.h 3 Dec 2014 04:04:30 -0000
@@ -229,7 +229,7 @@ struct lacp_softc {
LIST_HEAD(, lacp_port) lsc_ports;
struct lacp_portmap lsc_pmap[2];
volatile u_int lsc_activemap;
- u_int32_t lsc_hashkey;
+ SIPHASH_KEY lsc_hashkey;
};
#define LACP_TYPE_ACTORINFO 1