From: Jan Klemkow Subject: bridge(4): use vlan hardware tagging To: tech@openbsd.org Date: Mon, 4 Aug 2025 12:02:30 +0200 Hi, This diff adds the use of VLAN hardware tagging in bridge(4) and vether(4) similar to veb(4). ok? bye, Jan Index: net/if_bridge.c =================================================================== RCS file: /cvs/src/sys/net/if_bridge.c,v diff -u -p -r1.376 if_bridge.c --- net/if_bridge.c 7 Jul 2025 02:28:50 -0000 1.376 +++ net/if_bridge.c 4 Aug 2025 08:13:23 -0000 @@ -798,6 +798,24 @@ bridge_stop(struct bridge_softc *sc) bridge_rtflush(sc, IFBF_FLUSHDYN); } +struct mbuf * +bridge_offload(struct ifnet *ifp, struct mbuf *m) +{ +#if NVLAN > 0 + /* + * If the underlying interface has no VLAN hardware tagging support, + * inject one in software. + */ + if (ISSET(m->m_flags, M_VLANTAG) && + !ISSET(ifp->if_capabilities, IFCAP_VLAN_HWTAGGING)) { + m = vlan_inject(m, ETHERTYPE_VLAN, m->m_pkthdr.ether_vtag); + if (m == NULL) + return NULL; + } +#endif + return m; +} + /* * Send output from the bridge. The mbuf has the ethernet header * already attached. We must enqueue or free the mbuf before exiting. @@ -897,6 +915,9 @@ bridge_enqueue(struct ifnet *ifp, struct continue; } + if ((mc = bridge_offload(dst_if, mc)) == NULL) + goto out; + error = bridge_ifenqueue(brifp, dst_if, mc); if (error) continue; @@ -914,6 +935,9 @@ bridge_enqueue(struct ifnet *ifp, struct goto out; } + if ((m = bridge_offload(dst_if, m)) == NULL) + goto out; + bridge_ifenqueue(brifp, dst_if, m); if_put(dst_if); out: @@ -1093,6 +1117,9 @@ bridgeintr_frame(struct ifnet *brifp, st if (m == NULL) goto bad; + if ((m = bridge_offload(dst_if, m)) == NULL) + goto bad; + len = m->m_pkthdr.len; #if NVLAN > 0 if ((m->m_flags & M_VLANTAG) && @@ -1170,18 +1197,6 @@ bridge_process(struct ifnet *ifp, struct if (m->m_pkthdr.len < sizeof(*eh)) goto bad; -#if NVLAN > 0 - /* - * If the underlying interface removed the VLAN header itself, - * add it back. - */ - if (ISSET(m->m_flags, M_VLANTAG)) { - m = vlan_inject(m, ETHERTYPE_VLAN, m->m_pkthdr.ether_vtag); - if (m == NULL) - goto bad; - } -#endif - #if NBPFILTER > 0 if_bpf = brifp->if_bpf; if (if_bpf) @@ -1358,6 +1373,9 @@ bridge_broadcast(struct bridge_softc *sc if (mc == NULL) continue; + if ((mc = bridge_offload(dst_if, mc)) == NULL) + goto bad; + len = mc->m_pkthdr.len; #if NVLAN > 0 if ((mc->m_flags & M_VLANTAG) && @@ -1371,6 +1389,7 @@ bridge_broadcast(struct bridge_softc *sc } } + bad: if (!used) m_freem(m); } @@ -1425,6 +1444,11 @@ bridge_span(struct ifnet *brifp, struct if ((ifp->if_flags & IFF_RUNNING) == 0) continue; + + if ((m = bridge_offload(ifp, m)) == NULL) { + brifp->if_oerrors++; + continue; + } mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); if (mc == NULL) { Index: net/if_vether.c =================================================================== RCS file: /cvs/src/sys/net/if_vether.c,v diff -u -p -r1.37 if_vether.c --- net/if_vether.c 7 Jul 2025 02:28:50 -0000 1.37 +++ net/if_vether.c 3 Aug 2025 16:12:48 -0000 @@ -27,6 +27,7 @@ #include #include +#include "vlan.h" #include "bpfilter.h" #if NBPFILTER > 0 #include @@ -85,6 +86,9 @@ vether_clone_create(struct if_clone *ifc ifp->if_hardmtu = ETHER_MAX_HARDMTU_LEN; ifp->if_capabilities = IFCAP_VLAN_MTU; +#if NVLAN > 0 + ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; +#endif ifp->if_xflags = IFXF_CLONED | IFXF_MPSAFE; ifmedia_init(&sc->sc_media, 0, vether_media_change,