use a uint64_t for the ethernet address in the etherbridge table.
authordlg <dlg@openbsd.org>
Fri, 26 Feb 2021 01:28:51 +0000 (01:28 +0000)
committerdlg <dlg@openbsd.org>
Fri, 26 Feb 2021 01:28:51 +0000 (01:28 +0000)
testing has shown up to a 30% improvement in the veb forwarding
rate with this change.

an earlier diff was tested by hrvoje popovski
tested on amd64 and sparc64

sys/net/if_bpe.c
sys/net/if_etherbridge.c
sys/net/if_etherbridge.h
sys/net/if_gre.c
sys/net/if_veb.c

index 9f008b5..1a4b752 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_bpe.c,v 1.17 2021/02/24 02:04:03 dlg Exp $ */
+/*     $OpenBSD: if_bpe.c,v 1.18 2021/02/26 01:28:51 dlg Exp $ */
 /*
  * Copyright (c) 2018 David Gwynne <dlg@openbsd.org>
  *
@@ -268,7 +268,7 @@ bpe_start(struct ifnet *ifp)
                        struct ether_addr *endpoint;
 
                        smr_read_enter();
-                       endpoint = etherbridge_resolve(&sc->sc_eb,
+                       endpoint = etherbridge_resolve_ea(&sc->sc_eb,
                            (struct ether_addr *)ceh->ether_dhost);
                        if (endpoint == NULL) {
                                /* "flood" to unknown hosts */
@@ -763,7 +763,7 @@ bpe_input(struct ifnet *ifp0, struct mbuf *m)
 
        ceh = (struct ether_header *)(itagp + 1);
 
-       etherbridge_map(&sc->sc_eb, ceh->ether_shost,
+       etherbridge_map_ea(&sc->sc_eb, ceh->ether_shost,
            (struct ether_addr *)beh->ether_shost);
 
        m_adj(m, sizeof(*beh) + sizeof(*itagp));
index 03ee76c..451781a 100644 (file)
@@ -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.4 2021/02/26 01:28:51 dlg Exp $ */
 
 /*
  * Copyright (c) 2018, 2021 David Gwynne <dlg@openbsd.org>
@@ -156,20 +156,22 @@ etherbridge_destroy(struct etherbridge *eb)
 }
 
 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);
-       hash &= ETHERBRIDGE_TABLE_MASK;
+       uint16_t hash;
+
+       hash = stoeplitz_h64(eba) & 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 +193,11 @@ ebl_remove(struct eb_list *ebl, struct eb_entry *ebe)
 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)));
+       if (aebe->ebe_addr > bebe->ebe_addr)
+               return (1);
+       if (aebe->ebe_addr < bebe->ebe_addr)
+               return (-1);
+       return (0);
 }
 
 RBT_GENERATE(eb_tree, eb_entry, ebe_tentry, ebt_cmp);
@@ -251,14 +256,21 @@ ebe_free(void *arg)
 }
 
 void *
-etherbridge_resolve(struct etherbridge *eb, const struct ether_addr *ea)
+etherbridge_resolve_ea(struct etherbridge *eb,
+    const struct ether_addr *ea)
+{
+       return (etherbridge_resolve(eb, ether_addr_to_e64(ea)));
+}
+
+void *
+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 +285,14 @@ etherbridge_resolve(struct etherbridge *eb, const struct ether_addr *ea)
 }
 
 void
-etherbridge_map(struct etherbridge *eb, void *port,
+etherbridge_map_ea(struct etherbridge *eb, void *port,
     const struct ether_addr *ea)
+{
+       etherbridge_map(eb, port, ether_addr_to_e64(ea));
+}
+
+void
+etherbridge_map(struct etherbridge *eb, void *port, uint64_t eba)
 {
        struct eb_list *ebl;
        struct eb_entry *oebe, *nebe;
@@ -282,14 +300,13 @@ etherbridge_map(struct etherbridge *eb, void *port,
        void *nport;
        int new = 0;
 
-       if (ETHER_IS_MULTICAST(ea->ether_addr_octet) ||
-           ETHER_IS_EQ(ea->ether_addr_octet, etheranyaddr))
+       if (ETH64_IS_MULTICAST(eba) || ETH64_IS_ANYADDR(eba))
                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 +342,7 @@ etherbridge_map(struct etherbridge *eb, void *port,
        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 +391,14 @@ int
 etherbridge_add_addr(struct etherbridge *eb, void *port,
     const struct ether_addr *ea, unsigned int type)
 {
+       uint64_t eba = ether_addr_to_e64(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 (ETH64_IS_MULTICAST(eba) || ETH64_IS_ANYADDR(eba))
                return (EADDRNOTAVAIL);
 
        nport = eb_port_take(eb, port);
@@ -398,12 +415,12 @@ etherbridge_add_addr(struct etherbridge *eb, void *port,
        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 +448,15 @@ etherbridge_add_addr(struct etherbridge *eb, void *port,
 int
 etherbridge_del_addr(struct etherbridge *eb, const struct ether_addr *ea)
 {
+       uint64_t eba = ether_addr_to_e64(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);
@@ -607,8 +625,7 @@ etherbridge_rtfind(struct etherbridge *eb, struct ifbaconf *baconf)
                eb_port_ifname(eb,
                    bareq.ifba_ifsname, sizeof(bareq.ifba_ifsname),
                    ebe->ebe_port);
-               memcpy(&bareq.ifba_dst, &ebe->ebe_addr,
-                   sizeof(bareq.ifba_dst));
+               ether_e64_to_addr(&bareq.ifba_dst, ebe->ebe_addr);
 
                memset(&bareq.ifba_dstsa, 0, sizeof(bareq.ifba_dstsa));
                eb_port_sa(eb, &bareq.ifba_dstsa, ebe->ebe_port);
index fa675b4..e5246cd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_etherbridge.h,v 1.2 2021/02/24 01:20:03 dlg Exp $ */
+/*     $OpenBSD: if_etherbridge.h,v 1.3 2021/02/26 01:28:51 dlg Exp $ */
 
 /*
  * Copyright (c) 2018, 2021 David Gwynne <dlg@openbsd.org>
@@ -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,12 @@ 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_map_ea(struct etherbridge *, void *,
+            const struct ether_addr *);
+void   *etherbridge_resolve(struct etherbridge *, uint64_t);
+void   *etherbridge_resolve_ea(struct etherbridge *,
+            const struct ether_addr *);
 void    etherbridge_detach_port(struct etherbridge *, void *);
 
 /* ioctl support */
index ec4344e..12b4c93 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_gre.c,v 1.167 2021/02/24 03:20:48 dlg Exp $ */
+/*     $OpenBSD: if_gre.c,v 1.168 2021/02/26 01:28:51 dlg Exp $ */
 /*     $NetBSD: if_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */
 
 /*
@@ -1363,7 +1363,7 @@ nvgre_input(const struct gre_tunnel *key, struct mbuf *m, int hlen,
                return (0);
 
        eh = mtod(m, struct ether_header *);
-       etherbridge_map(&sc->sc_eb, (void *)&key->t_dst,
+       etherbridge_map_ea(&sc->sc_eb, (void *)&key->t_dst,
            (struct ether_addr *)eh->ether_shost);
 
        SET(m->m_pkthdr.csum_flags, M_FLOWID);
@@ -3658,7 +3658,7 @@ nvgre_start(struct ifnet *ifp)
                        const union gre_addr *endpoint;
 
                        smr_read_enter();
-                       endpoint = etherbridge_resolve(&sc->sc_eb,
+                       endpoint = etherbridge_resolve_ea(&sc->sc_eb,
                            (struct ether_addr *)eh->ether_dhost);
                        if (endpoint == NULL) {
                                /* "flood" to unknown hosts */
index 3df480c..72f113e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_veb.c,v 1.9 2021/02/26 00:16:41 deraadt Exp $ */
+/*     $OpenBSD: if_veb.c,v 1.10 2021/02/26 01:28:51 dlg Exp $ */
 
 /*
  * Copyright (c) 2021 David Gwynne <dlg@openbsd.org>
 #include <net/if_vlan_var.h>
 #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 } }
-};
-
 /* SIOCBRDGIFFLGS, SIOCBRDGIFFLGS */
 #define VEB_IFBIF_FLAGS        (IFBIF_LEARNING|IFBIF_DISCOVER|IFBIF_BLOCKNONIP)
 
@@ -932,7 +920,7 @@ veb_port_input(struct ifnet *ifp0, struct mbuf *m, void *brport)
        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 +934,10 @@ veb_port_input(struct ifnet *ifp0, struct mbuf *m, void *brport)
                return (m);
 
        eh = mtod(m, struct ether_header *);
-       dst.ea = *(struct ether_addr *)eh->ether_dhost;
+       dst = ether_addr_to_e64((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 (ETH64_IS_8021_RSVD(dst))
                goto drop;
 
 #if NVLAN > 0
@@ -1008,19 +996,18 @@ veb_port_input(struct ifnet *ifp0, struct mbuf *m, void *brport)
        eh = mtod(m, struct ether_header *);
 
        if (ISSET(p->p_bif_flags, IFBIF_LEARNING)) {
-               etherbridge_map(&sc->sc_eb, p,
+               etherbridge_map_ea(&sc->sc_eb, p,
                    (struct ether_addr *)eh->ether_shost);
        }
 
        CLR(m->m_flags, M_BCAST|M_MCAST);
        SET(m->m_flags, M_PROTO1);
 
-       if (!ETHER_IS_MULTICAST(eh->ether_dhost)) {
+       if (!ETH64_IS_MULTICAST(dst)) {
                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();
 
@@ -1029,8 +1016,7 @@ veb_port_input(struct ifnet *ifp0, struct mbuf *m, void *brport)
 
                /* unknown unicast address */
        } else {
-               SET(m->m_flags,
-                   ETHER_IS_BROADCAST(eh->ether_dhost) ? M_BCAST : M_MCAST);
+               SET(m->m_flags, ETH64_IS_BROADCAST(dst) ? M_BCAST : M_MCAST);
        }
 
        veb_broadcast(sc, p, m);