lagg: change hash logic to generate the same value
when pairs of source and destination are the same
This commit is contained in:
parent
317dcfdb56
commit
e903d516ab
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: if_lagg.c,v 1.16 2021/10/19 08:02:42 yamaguchi Exp $ */
|
/* $NetBSD: if_lagg.c,v 1.17 2021/10/22 06:20:47 yamaguchi Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
|
* Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: if_lagg.c,v 1.16 2021/10/19 08:02:42 yamaguchi Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: if_lagg.c,v 1.17 2021/10/22 06:20:47 yamaguchi Exp $");
|
||||||
|
|
||||||
#ifdef _KERNEL_OPT
|
#ifdef _KERNEL_OPT
|
||||||
#include "opt_inet.h"
|
#include "opt_inet.h"
|
||||||
|
@ -876,7 +876,7 @@ lagg_hashmbuf(struct lagg_softc *sc, struct mbuf *m)
|
||||||
const struct ip6_hdr *ip6;
|
const struct ip6_hdr *ip6;
|
||||||
const struct tcphdr *th;
|
const struct tcphdr *th;
|
||||||
const struct udphdr *uh;
|
const struct udphdr *uh;
|
||||||
uint32_t hash = HASH32_BUF_INIT;
|
uint32_t hash, hash_src, hash_dst;
|
||||||
uint32_t flowlabel;
|
uint32_t flowlabel;
|
||||||
uint16_t etype, vlantag;
|
uint16_t etype, vlantag;
|
||||||
uint8_t proto;
|
uint8_t proto;
|
||||||
|
@ -884,9 +884,17 @@ lagg_hashmbuf(struct lagg_softc *sc, struct mbuf *m)
|
||||||
|
|
||||||
KASSERT(ISSET(m->m_flags, M_PKTHDR));
|
KASSERT(ISSET(m->m_flags, M_PKTHDR));
|
||||||
|
|
||||||
|
hash = HASH32_BUF_INIT;
|
||||||
|
hash_src = HASH32_BUF_INIT;
|
||||||
|
hash_dst = HASH32_BUF_INIT;
|
||||||
|
|
||||||
|
#define LAGG_HASH_ADD(hp, v) do { \
|
||||||
|
*(hp) = hash32_buf(&(v), sizeof(v), *(hp)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
eh = lagg_m_extract(m, 0, sizeof(*eh), &buf);
|
eh = lagg_m_extract(m, 0, sizeof(*eh), &buf);
|
||||||
if (eh == NULL) {
|
if (eh == NULL) {
|
||||||
return hash;
|
goto out;
|
||||||
}
|
}
|
||||||
off = ETHER_HDR_LEN;
|
off = ETHER_HDR_LEN;
|
||||||
etype = ntohs(eh->ether_type);
|
etype = ntohs(eh->ether_type);
|
||||||
|
@ -894,7 +902,7 @@ lagg_hashmbuf(struct lagg_softc *sc, struct mbuf *m)
|
||||||
if (etype == ETHERTYPE_VLAN) {
|
if (etype == ETHERTYPE_VLAN) {
|
||||||
evl = lagg_m_extract(m, 0, sizeof(*evl), &buf);
|
evl = lagg_m_extract(m, 0, sizeof(*evl), &buf);
|
||||||
if (evl == NULL) {
|
if (evl == NULL) {
|
||||||
return hash;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
vlantag = ntohs(evl->evl_tag);
|
vlantag = ntohs(evl->evl_tag);
|
||||||
|
@ -907,26 +915,22 @@ lagg_hashmbuf(struct lagg_softc *sc, struct mbuf *m)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc->sc_hash_mac) {
|
if (sc->sc_hash_mac) {
|
||||||
hash = hash32_buf(&eh->ether_dhost,
|
LAGG_HASH_ADD(&hash_dst, eh->ether_dhost);
|
||||||
sizeof(eh->ether_dhost), hash);
|
LAGG_HASH_ADD(&hash_src, eh->ether_shost);
|
||||||
hash = hash32_buf(&eh->ether_shost,
|
LAGG_HASH_ADD(&hash, vlantag);
|
||||||
sizeof(eh->ether_shost), hash);
|
|
||||||
hash = hash32_buf(&vlantag, sizeof(vlantag), hash);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (etype) {
|
switch (etype) {
|
||||||
case ETHERTYPE_IP:
|
case ETHERTYPE_IP:
|
||||||
ip = lagg_m_extract(m, off, sizeof(*ip), &buf);
|
ip = lagg_m_extract(m, off, sizeof(*ip), &buf);
|
||||||
if (ip == NULL) {
|
if (ip == NULL) {
|
||||||
return hash;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc->sc_hash_ipaddr) {
|
if (sc->sc_hash_ipaddr) {
|
||||||
hash = hash32_buf(&ip->ip_src,
|
LAGG_HASH_ADD(&hash_src, ip->ip_src);
|
||||||
sizeof(ip->ip_src), hash);
|
LAGG_HASH_ADD(&hash_dst, ip->ip_dst);
|
||||||
hash = hash32_buf(&ip->ip_dst,
|
LAGG_HASH_ADD(&hash, ip->ip_p);
|
||||||
sizeof(ip->ip_dst), hash);
|
|
||||||
hash = hash32_buf(&ip->ip_p, sizeof(ip->ip_p), hash);
|
|
||||||
}
|
}
|
||||||
off += ip->ip_hl << 2;
|
off += ip->ip_hl << 2;
|
||||||
proto = ip->ip_p;
|
proto = ip->ip_p;
|
||||||
|
@ -934,22 +938,19 @@ lagg_hashmbuf(struct lagg_softc *sc, struct mbuf *m)
|
||||||
case ETHERTYPE_IPV6:
|
case ETHERTYPE_IPV6:
|
||||||
ip6 = lagg_m_extract(m, off, sizeof(*ip6), &buf);
|
ip6 = lagg_m_extract(m, off, sizeof(*ip6), &buf);
|
||||||
if (ip6 == NULL) {
|
if (ip6 == NULL) {
|
||||||
return hash;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc->sc_hash_ip6addr) {
|
if (sc->sc_hash_ip6addr) {
|
||||||
hash = hash32_buf(&ip6->ip6_src,
|
LAGG_HASH_ADD(&hash_src, ip6->ip6_src);
|
||||||
sizeof(ip6->ip6_src), hash);
|
LAGG_HASH_ADD(&hash_dst, ip6->ip6_dst);
|
||||||
hash = hash32_buf(&ip6->ip6_dst,
|
|
||||||
sizeof(ip6->ip6_dst), hash);
|
|
||||||
flowlabel = ip6->ip6_flow & IPV6_FLOWLABEL_MASK;
|
flowlabel = ip6->ip6_flow & IPV6_FLOWLABEL_MASK;
|
||||||
hash = hash32_buf(&flowlabel, sizeof(flowlabel), hash);
|
LAGG_HASH_ADD(&hash, flowlabel);
|
||||||
}
|
}
|
||||||
proto = ip6->ip6_nxt;
|
proto = ip6->ip6_nxt;
|
||||||
off += sizeof(*ip6);
|
off += sizeof(*ip6);
|
||||||
|
break;
|
||||||
|
|
||||||
/* L4 header is not supported */
|
|
||||||
return hash;
|
|
||||||
default:
|
default:
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -958,31 +959,32 @@ lagg_hashmbuf(struct lagg_softc *sc, struct mbuf *m)
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
th = lagg_m_extract(m, off, sizeof(*th), &buf);
|
th = lagg_m_extract(m, off, sizeof(*th), &buf);
|
||||||
if (th == NULL) {
|
if (th == NULL) {
|
||||||
return hash;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc->sc_hash_tcp) {
|
if (sc->sc_hash_tcp) {
|
||||||
hash = hash32_buf(&th->th_sport,
|
LAGG_HASH_ADD(&hash_src, th->th_sport);
|
||||||
sizeof(th->th_sport), hash);
|
LAGG_HASH_ADD(&hash_dst, th->th_dport);
|
||||||
hash = hash32_buf(&th->th_dport,
|
|
||||||
sizeof(th->th_dport), hash);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP:
|
||||||
uh = lagg_m_extract(m, off, sizeof(*uh), &buf);
|
uh = lagg_m_extract(m, off, sizeof(*uh), &buf);
|
||||||
if (uh == NULL) {
|
if (uh == NULL) {
|
||||||
return hash;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc->sc_hash_udp) {
|
if (sc->sc_hash_udp) {
|
||||||
hash = hash32_buf(&uh->uh_sport,
|
LAGG_HASH_ADD(&hash_src, uh->uh_sport);
|
||||||
sizeof(uh->uh_sport), hash);
|
LAGG_HASH_ADD(&hash_dst, uh->uh_dport);
|
||||||
hash = hash32_buf(&uh->uh_dport,
|
|
||||||
sizeof(uh->uh_dport), hash);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
hash_src ^= hash_dst;
|
||||||
|
LAGG_HASH_ADD(&hash, hash_src);
|
||||||
|
#undef LAGG_HASH_ADD
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue