Download raw body.
vport(4): Use VLAN HW Tagging
Hi,
the following diff introduces VLAN offload to vport(4). veb(4) just
calls vlan_inject() if the underlying send interface it not capable of
hw tagging. So, we don't call it in most cases and avoid an mget() for
every packet.
ok?
bye,
Jan
Index: net/if_veb.c
===================================================================
RCS file: /cvs/src/sys/net/if_veb.c,v
diff -u -p -r1.37 if_veb.c
--- net/if_veb.c 2 Mar 2025 21:28:32 -0000 1.37
+++ net/if_veb.c 23 Jun 2025 15:06:54 -0000
@@ -927,6 +927,27 @@ veb_ipsec_out(struct ifnet *ifp0, struct
}
#endif /* IPSEC */
+static struct mbuf *
+veb_offload(struct ifnet *ifp, struct mbuf *m)
+{
+#if NVLAN > 0
+ if (ISSET(m->m_flags, M_VLANTAG) &&
+ !ISSET(ifp->if_capabilities, IFCAP_VLAN_HWTAGGING)) {
+ /*
+ * If the underlying interface has no VLAN hardware tagging
+ * support, inject one in software.
+ */
+ m = vlan_inject(m, ETHERTYPE_VLAN, m->m_pkthdr.ether_vtag);
+ if (m == NULL) {
+ counters_inc(ifp->if_counters, ifc_ierrors);
+ return NULL;
+ }
+ }
+#endif
+
+ return m;
+}
+
static void
veb_broadcast(struct veb_softc *sc, struct veb_port *rp, struct mbuf *m0,
uint64_t src, uint64_t dst, struct netstack *ns)
@@ -996,6 +1017,9 @@ veb_broadcast(struct veb_softc *sc, stru
if (veb_rule_filter(tp, VEB_RULE_LIST_OUT, m0, src, dst))
continue;
+ if ((m0 = veb_offload(ifp0, m0)) == NULL)
+ goto done;
+
m = m_dup_pkt(m0, max_linkhdr + ETHER_ALIGN, M_NOWAIT);
if (m == NULL) {
/* XXX count error? */
@@ -1048,6 +1072,9 @@ veb_transmit(struct veb_softc *sc, struc
counters_pkt(ifp->if_counters, ifc_opackets, ifc_obytes,
m->m_pkthdr.len);
+ if ((m = veb_offload(ifp0, m)) == NULL)
+ goto drop;
+
(*tp->p_enqueue)(ifp0, m); /* XXX count error */
return (NULL);
@@ -1105,20 +1132,6 @@ veb_port_input(struct ifnet *ifp0, struc
}
}
-#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) {
- counters_inc(ifp->if_counters, ifc_ierrors);
- goto drop;
- }
- }
-#endif
-
counters_pkt(ifp->if_counters, ifc_ipackets, ifc_ibytes,
m->m_pkthdr.len);
@@ -2349,6 +2362,7 @@ vport_clone_create(struct if_clone *ifc,
ifp->if_qstart = vport_start;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_xflags = IFXF_CLONED | IFXF_MPSAFE;
+ ifp->if_capabilities = IFCAP_VLAN_HWTAGGING;
ether_fakeaddr(ifp);
if_counters_alloc(ifp);
vport(4): Use VLAN HW Tagging