Download raw body.
bridge(4): use vlan hardware tagging
Hello Jan,
Am Mon, Aug 04, 2025 at 12:02:30PM +0200 schrieb Jan Klemkow:
> This diff adds the use of VLAN hardware tagging in bridge(4) and
> vether(4) similar to veb(4).
I've had a look at your diff. I simplified it by calling bridge_offload
at the beginning of bridge_ifenqueue. I've tested this diff with vlan(4),
vether(4) and ix(4) interfaces. I disabled the IFCAP_VLAN_HWTAGGING flag
in the ix(4) source code to test the vlan inject call path.
It worked as expected in my setup.
regards
Timo
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 13 Aug 2025 12:44:19 -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.
@@ -1170,18 +1188,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)
@@ -1915,21 +1921,29 @@ bridge_ifenqueue(struct ifnet *brifp, st
{
int error, len;
+ if ((m = bridge_offload(ifp, m)) == NULL) {
+ error = ENOBUFS;
+ goto err;
+ }
+
/* Loop prevention. */
m->m_flags |= M_PROTO1;
len = m->m_pkthdr.len;
error = if_enqueue(ifp, m);
- if (error) {
- brifp->if_oerrors++;
- return (error);
- }
+ if (error)
+ goto err;
+
brifp->if_opackets++;
brifp->if_obytes += len;
return (0);
+
+ err:
+ brifp->if_oerrors++;
+ return (error);
}
void
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 8 Aug 2025 14:11:52 -0000
@@ -27,6 +27,7 @@
#include <netinet/in.h>
#include <netinet/if_ether.h>
+#include "vlan.h"
#include "bpfilter.h"
#if NBPFILTER > 0
#include <net/bpf.h>
@@ -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,
bridge(4): use vlan hardware tagging