Stuart Henderson(st...@openbsd.org) on 2014.12.11 23:52:44 +:
I'm wondering what reception this will get. It feeds TCP/UDP port
numbers into the hash for trunk(4) load balancing, so connections
between a single pair of hosts will get distributed across NICs.
Taken from FreeBSD r232629, they also added SIOC[CS]LAGGHASH ioctls
so that the hash type can be configured in ifconfig (l2/l3/l4),
I haven't done that but could if there's no general objection to
this.
i like this, and i think it might be good to have it optional in case it
causes problems with other equipment.
Benno
This method is used on some switches too (e.g. trunk-load-balance
L4-based on HP 2530 and 5400zl).
Index: if_trunk.c
===
RCS file: /cvs/src/sys/net/if_trunk.c,v
retrieving revision 1.93
diff -u -p -r1.93 if_trunk.c
--- if_trunk.c4 Dec 2014 00:01:53 - 1.93
+++ if_trunk.c11 Dec 2014 23:45:20 -
@@ -978,12 +978,23 @@ trunk_hashmbuf(struct mbuf *m, SIPHASH_K
int off;
struct ether_header *eh;
#ifdef INET
- struct ip *ip, ipbuf;
+ struct ip *ip;
+ u_int32_t *ports;
+ int iphlen;
#endif
#ifdef INET6
u_int32_t flow;
struct ip6_hdr *ip6, ip6buf;
#endif
+ union {
+#ifdef INET
+ struct ip ip;
+#endif
+#ifdef INET6
+ struct ip6_hdr ip6;
+#endif
+ uint32_t port;
+} buf;
SIPHASH_CTX ctx;
SipHash24_Init(ctx, key);
@@ -1013,10 +1024,25 @@ trunk_hashmbuf(struct mbuf *m, SIPHASH_K
#ifdef INET
case ETHERTYPE_IP:
if ((ip = (struct ip *)
- trunk_gethdr(m, off, sizeof(*ip), ipbuf)) == NULL)
+ trunk_gethdr(m, off, sizeof(*ip), buf)) == NULL)
return (p);
SipHash24_Update(ctx, ip-ip_src, sizeof(struct in_addr));
SipHash24_Update(ctx, ip-ip_dst, sizeof(struct in_addr));
+
+ /* l4 hash */
+ switch (ip-ip_p) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ iphlen = ip-ip_hl 2;
+ if (iphlen sizeof(*ip))
+ break;
+ off += iphlen;
+ ports = (u_int32_t *) trunk_gethdr(m, off,
sizeof(*ports), buf);
+ if (ports == NULL)
+ break;
+ SipHash24_Update(ctx, ports, sizeof(*ports));
+ break;
+ }
break;
#endif
#ifdef INET6
--