Index: if_etherbridge.c =================================================================== RCS file: /cvs/src/sys/net/if_etherbridge.c,v retrieving revision 1.3 diff -u -p -r1.3 if_etherbridge.c --- if_etherbridge.c 24 Feb 2021 08:23:04 -0000 1.3 +++ if_etherbridge.c 24 Feb 2021 08:48:25 -0000 @@ -1,4 +1,4 @@ -/* $OpenBSD: if_etherbridge.c,v 1.3 2021/02/24 08:23:04 dlg Exp $ */ +/* $OpenBSD: if_etherbridge.c,v 1.2 2021/02/24 01:20:03 dlg Exp $ */ /* * Copyright (c) 2018, 2021 David Gwynne @@ -156,20 +156,26 @@ etherbridge_destroy(struct etherbridge * } static struct eb_list * -etherbridge_list(struct etherbridge *eb, const struct ether_addr *ea) +etherbridge_list(struct etherbridge *eb, uint64_t eba) { - uint16_t hash = stoeplitz_eaddr(ea->ether_addr_octet); + uint16_t hash; + + eba ^= eba >> 32; + eba ^= eba >> 16; + + hash = stoeplitz_h16(eba); hash &= ETHERBRIDGE_TABLE_MASK; + return (&eb->eb_table[hash]); } static struct eb_entry * -ebl_find(struct eb_list *ebl, const struct ether_addr *ea) +ebl_find(struct eb_list *ebl, uint64_t eba) { struct eb_entry *ebe; SMR_TAILQ_FOREACH(ebe, ebl, ebe_lentry) { - if (ETHER_IS_EQ(ea, &ebe->ebe_addr)) + if (ebe->ebe_addr == eba) return (ebe); } @@ -191,8 +197,7 @@ ebl_remove(struct eb_list *ebl, struct e static inline int ebt_cmp(const struct eb_entry *aebe, const struct eb_entry *bebe) { - return (memcmp(&aebe->ebe_addr, &bebe->ebe_addr, - sizeof(aebe->ebe_addr))); + return (aebe->ebe_addr - bebe->ebe_addr); } RBT_GENERATE(eb_tree, eb_entry, ebe_tentry, ebt_cmp); @@ -251,14 +256,14 @@ ebe_free(void *arg) } void * -etherbridge_resolve(struct etherbridge *eb, const struct ether_addr *ea) +etherbridge_resolve(struct etherbridge *eb, uint64_t eba) { - struct eb_list *ebl = etherbridge_list(eb, ea); + struct eb_list *ebl = etherbridge_list(eb, eba); struct eb_entry *ebe; SMR_ASSERT_CRITICAL(); - ebe = ebl_find(ebl, ea); + ebe = ebl_find(ebl, eba); if (ebe != NULL) { if (ebe->ebe_type == EBE_DYNAMIC) { int diff = getuptime() - ebe->ebe_age; @@ -273,8 +278,7 @@ etherbridge_resolve(struct etherbridge * } void -etherbridge_map(struct etherbridge *eb, void *port, - const struct ether_addr *ea) +etherbridge_map(struct etherbridge *eb, void *port, uint64_t eba) { struct eb_list *ebl; struct eb_entry *oebe, *nebe; @@ -282,14 +286,13 @@ etherbridge_map(struct etherbridge *eb, void *nport; int new = 0; - if (ETHER_IS_MULTICAST(ea->ether_addr_octet) || - ETHER_IS_EQ(ea->ether_addr_octet, etheranyaddr)) + if ((eba & 0x010000000000) || (eba == 0)) return; - ebl = etherbridge_list(eb, ea); + ebl = etherbridge_list(eb, eba); smr_read_enter(); - oebe = ebl_find(ebl, ea); + oebe = ebl_find(ebl, eba); if (oebe == NULL) new = 1; else { @@ -325,7 +328,7 @@ etherbridge_map(struct etherbridge *eb, refcnt_init(&nebe->ebe_refs); nebe->ebe_etherbridge = eb; - nebe->ebe_addr = *ea; + nebe->ebe_addr = eba; nebe->ebe_port = nport; nebe->ebe_type = EBE_DYNAMIC; nebe->ebe_age = getuptime(); @@ -374,14 +377,14 @@ int etherbridge_add_addr(struct etherbridge *eb, void *port, const struct ether_addr *ea, unsigned int type) { + uint64_t eba = eb_addr_get(ea); struct eb_list *ebl; struct eb_entry *nebe; unsigned int num; void *nport; int error = 0; - if (ETHER_IS_MULTICAST(ea->ether_addr_octet) || - ETHER_IS_EQ(ea->ether_addr_octet, etheranyaddr)) + if ((eba & 0x010000000000) || (eba == 0)) return (EADDRNOTAVAIL); nport = eb_port_take(eb, port); @@ -398,12 +401,12 @@ etherbridge_add_addr(struct etherbridge refcnt_init(&nebe->ebe_refs); nebe->ebe_etherbridge = eb; - nebe->ebe_addr = *ea; + nebe->ebe_addr = eba; nebe->ebe_port = nport; nebe->ebe_type = type; nebe->ebe_age = getuptime(); - ebl = etherbridge_list(eb, ea); + ebl = etherbridge_list(eb, eba); mtx_enter(&eb->eb_lock); num = eb->eb_num + 1; @@ -431,14 +434,15 @@ etherbridge_add_addr(struct etherbridge int etherbridge_del_addr(struct etherbridge *eb, const struct ether_addr *ea) { + uint64_t eba = eb_addr_get(ea); struct eb_list *ebl; struct eb_entry *oebe; const struct eb_entry key = { - .ebe_addr = *ea, + .ebe_addr = eba, }; int error = 0; - ebl = etherbridge_list(eb, ea); + ebl = etherbridge_list(eb, eba); mtx_enter(&eb->eb_lock); oebe = ebt_find(eb, &key); @@ -678,4 +682,29 @@ etherbridge_get_tmo(struct etherbridge * bparam->ifbrp_ctime = eb->eb_max_age; return (0); +} + +uint64_t +eb_addr_get(const struct ether_addr *ea) +{ + uint64_t eba = 0; + size_t i; + + for (i = 0; i < nitems(ea->ether_addr_octet); i++) { + eba <<= 8; + eba |= ea->ether_addr_octet[i]; + } + + return (eba); +} + +void +eb_addr_set(struct ether_addr *ea, uint64_t eba) +{ + size_t i = nitems(ea->ether_addr_octet); + + do { + ea->ether_addr_octet[--i] = eba; + eba >>= 8; + } while (i > 0); } Index: if_etherbridge.h =================================================================== RCS file: /cvs/src/sys/net/if_etherbridge.h,v retrieving revision 1.2 diff -u -p -r1.2 if_etherbridge.h --- if_etherbridge.h 24 Feb 2021 01:20:03 -0000 1.2 +++ if_etherbridge.h 24 Feb 2021 08:48:25 -0000 @@ -42,7 +42,7 @@ struct eb_entry { #define ebe_tentry _ebe_entries._ebe_tentry #define ebe_qentry _ebe_entries._ebe_qentry - struct ether_addr ebe_addr; + uint64_t ebe_addr; void *ebe_port; unsigned int ebe_type; #define EBE_DYNAMIC 0x0 @@ -81,9 +81,8 @@ int etherbridge_up(struct etherbridge * int etherbridge_down(struct etherbridge *); void etherbridge_destroy(struct etherbridge *); -void etherbridge_map(struct etherbridge *, void *, - const struct ether_addr *); -void *etherbridge_resolve(struct etherbridge *, const struct ether_addr *); +void etherbridge_map(struct etherbridge *, void *, uint64_t); +void *etherbridge_resolve(struct etherbridge *, uint64_t); void etherbridge_detach_port(struct etherbridge *, void *); /* ioctl support */ @@ -102,5 +101,8 @@ etherbridge_num(const struct etherbridge { return (eb->eb_num); } + +uint64_t eb_addr_get(const struct ether_addr *); +void eb_addr_set(struct ether_addr *, uint64_t); #endif /* _NET_ETHERBRIDGE_H_ */ Index: if_veb.c =================================================================== RCS file: /cvs/src/sys/net/if_veb.c,v retrieving revision 1.8 diff -u -p -r1.8 if_veb.c --- if_veb.c 24 Feb 2021 01:20:03 -0000 1.8 +++ if_veb.c 24 Feb 2021 08:48:25 -0000 @@ -72,17 +72,8 @@ #include #endif -union veb_addr { - struct ether_addr ea; - uint64_t word; -}; - -static const union veb_addr veb_8021_group = { - .ea = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 } -}; -static const union veb_addr veb_8021_group_mask = { - .ea = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0 } -}; +#define IEEE8021_PREFIX 0x0180c2000000 +#define IEEE8021_PREFIX_MASK 0xfffffffffff0 /* SIOCBRDGIFFLGS, SIOCBRDGIFFLGS */ #define VEB_IFBIF_FLAGS (IFBIF_LEARNING|IFBIF_DISCOVER|IFBIF_BLOCKNONIP) @@ -932,7 +923,7 @@ veb_port_input(struct ifnet *ifp0, struc struct veb_softc *sc = p->p_veb; struct ifnet *ifp = &sc->sc_if; struct ether_header *eh; - union veb_addr dst = { .word = 0 }; + uint64_t dst; #if NBPFILTER > 0 caddr_t if_bpf; #endif @@ -946,10 +937,10 @@ veb_port_input(struct ifnet *ifp0, struc return (m); eh = mtod(m, struct ether_header *); - dst.ea = *(struct ether_addr *)eh->ether_dhost; + dst = eb_addr_get((struct ether_addr *)eh->ether_dhost); /* Is this a MAC Bridge component Reserved address? */ - if ((dst.word & veb_8021_group_mask.word) == veb_8021_group.word) + if ((dst & IEEE8021_PREFIX_MASK) == IEEE8021_PREFIX) goto drop; #if NVLAN > 0 @@ -1009,7 +1000,7 @@ veb_port_input(struct ifnet *ifp0, struc if (ISSET(p->p_bif_flags, IFBIF_LEARNING)) { etherbridge_map(&sc->sc_eb, p, - (struct ether_addr *)eh->ether_shost); + eb_addr_get((struct ether_addr *)eh->ether_shost)); } CLR(m->m_flags, M_BCAST|M_MCAST); @@ -1019,8 +1010,7 @@ veb_port_input(struct ifnet *ifp0, struc struct veb_port *tp = NULL; smr_read_enter(); - tp = etherbridge_resolve(&sc->sc_eb, - (struct ether_addr *)eh->ether_dhost); + tp = etherbridge_resolve(&sc->sc_eb, dst); m = veb_transmit(sc, p, tp, m); smr_read_leave(); Index: if_bpe.c =================================================================== RCS file: /cvs/src/sys/net/if_bpe.c,v retrieving revision 1.17 diff -u -p -r1.17 if_bpe.c --- if_bpe.c 24 Feb 2021 02:04:03 -0000 1.17 +++ if_bpe.c 24 Feb 2021 08:48:25 -0000 @@ -265,11 +265,13 @@ bpe_start(struct ifnet *ifp) memcpy(beh->ether_dhost, &sc->sc_group, sizeof(beh->ether_dhost)); } else { + uint64_t dst = eb_addr_get( + (struct ether_addr *)ceh->ether_dhost); struct ether_addr *endpoint; + smr_read_enter(); - endpoint = etherbridge_resolve(&sc->sc_eb, - (struct ether_addr *)ceh->ether_dhost); + endpoint = etherbridge_resolve(&sc->sc_eb, dst); if (endpoint == NULL) { /* "flood" to unknown hosts */ endpoint = &sc->sc_group; @@ -764,7 +766,7 @@ bpe_input(struct ifnet *ifp0, struct mbu ceh = (struct ether_header *)(itagp + 1); etherbridge_map(&sc->sc_eb, ceh->ether_shost, - (struct ether_addr *)beh->ether_shost); + eb_addr_get((struct ether_addr *)beh->ether_shost)); m_adj(m, sizeof(*beh) + sizeof(*itagp)); Index: if_gre.c =================================================================== RCS file: /cvs/src/sys/net/if_gre.c,v retrieving revision 1.167 diff -u -p -r1.167 if_gre.c --- if_gre.c 24 Feb 2021 03:20:48 -0000 1.167 +++ if_gre.c 24 Feb 2021 08:48:25 -0000 @@ -1364,7 +1364,7 @@ nvgre_input(const struct gre_tunnel *key eh = mtod(m, struct ether_header *); etherbridge_map(&sc->sc_eb, (void *)&key->t_dst, - (struct ether_addr *)eh->ether_shost); + eb_addr_get((struct ether_addr *)eh->ether_shost)); SET(m->m_pkthdr.csum_flags, M_FLOWID); m->m_pkthdr.ph_flowid = bemtoh32(&key->t_key) & ~GRE_KEY_ENTROPY; @@ -3659,7 +3659,7 @@ nvgre_start(struct ifnet *ifp) smr_read_enter(); endpoint = etherbridge_resolve(&sc->sc_eb, - (struct ether_addr *)eh->ether_dhost); + eb_addr_get((struct ether_addr *)eh->ether_dhost)); if (endpoint == NULL) { /* "flood" to unknown hosts */ endpoint = &tunnel->t_dst; Index: toeplitz.h =================================================================== RCS file: /cvs/src/sys/net/toeplitz.h,v retrieving revision 1.5 diff -u -p -r1.5 toeplitz.h --- toeplitz.h 21 Feb 2021 15:56:25 -0000 1.5 +++ toeplitz.h 24 Feb 2021 08:48:25 -0000 @@ -105,9 +105,9 @@ void stoeplitz_to_key(void *, size_t) extern const struct stoeplitz_cache *const stoeplitz_cache; #define stoeplitz_n16(_n16) \ - stoeplitz_cache_n16(stoeplitz_cache, (_n16)) + stoeplitz_hash_n16(stoeplitz_cache, (_n16)) #define stoeplitz_h16(_h16) \ - stoeplitz_cache_h16(stoeplitz_cache, (_h16)) + stoeplitz_hash_h16(stoeplitz_cache, (_h16)) #define stoeplitz_port(_p) stoeplitz_n16((_p)) #define stoeplitz_ip4(_sa4, _da4) \ stoeplitz_hash_ip4(stoeplitz_cache, (_sa4), (_da4))