The branch main has been updated by ivy: URL: https://cgit.FreeBSD.org/src/commit/?id=6a888f62413a1a6117f5053f124c97277ed18484
commit 6a888f62413a1a6117f5053f124c97277ed18484 Author: Lexi Winter <i...@freebsd.org> AuthorDate: 2025-09-12 21:03:00 +0000 Commit: Lexi Winter <i...@freebsd.org> CommitDate: 2025-09-12 21:03:00 +0000 bridge: Do outbound VLAN filtering in bridge_enqueue Outbound VLAN filtering wasn't being done for host-originated frames, because bridge_output was missing a call to bridge_vfilter_out, like in bridge_forward and bridge_broadcast. Rather than adding another call, move the filtering to bridge_enqueue, which ensures all frames will be filtered. This slightly changes the observable behaviour since we now do pfil before vlan filtering, but that's probably closer to what users expect anyway. MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D52380 --- sys/net/if_bridge.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index cea7f1cb5e23..d7911a348d87 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -2404,6 +2404,12 @@ bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m, return (EINVAL); } + /* Do VLAN filtering. */ + if (!bridge_vfilter_out(bif, m)) { + m_freem(m); + return (0); + } + /* We may be sending a fragment so traverse the mbuf */ for (; m; m = m0) { m0 = m->m_nextpkt; @@ -2823,10 +2829,6 @@ bridge_forward(struct bridge_softc *sc, struct bridge_iflist *sbif, if (sbif->bif_flags & dbif->bif_flags & IFBIF_PRIVATE) goto drop; - /* Do VLAN filtering. */ - if (!bridge_vfilter_out(dbif, m)) - goto drop; - if ((dbif->bif_flags & IFBIF_STP) && dbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) goto drop; @@ -3195,10 +3197,6 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, if (sbif && (sbif->bif_flags & dbif->bif_flags & IFBIF_PRIVATE)) continue; - /* Do VLAN filtering. */ - if (!bridge_vfilter_out(dbif, m)) - continue; - if ((dbif->bif_flags & IFBIF_STP) && dbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) continue; @@ -3364,6 +3362,14 @@ bridge_vfilter_out(const struct bridge_iflist *dbif, const struct mbuf *m) NET_EPOCH_ASSERT(); + /* + * If the interface is in span mode, then bif_sc will be NULL. + * Since the purpose of span interfaces is to receive all frames, + * pass everything. + */ + if (dbif->bif_sc == NULL) + return (true); + /* If VLAN filtering isn't enabled, pass everything. */ if ((dbif->bif_sc->sc_flags & IFBRF_VLANFILTER) == 0) return (true);