Download raw body.
bridge(4): use vlan hardware tagging
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 <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