Stuart Henderson(st...@openbsd.org) on 2014.12.11 23:52:44 +0000:
> 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.c        4 Dec 2014 00:01:53 -0000       1.93
> +++ if_trunk.c        11 Dec 2014 23:45:20 -0000
> @@ -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
> 

-- 

Reply via email to