diff options
| author | Lexi Winter <ivy@FreeBSD.org> | 2025-09-12 21:03:00 +0000 |
|---|---|---|
| committer | Lexi Winter <ivy@FreeBSD.org> | 2025-09-12 21:03:00 +0000 |
| commit | 6a888f62413a1a6117f5053f124c97277ed18484 (patch) | |
| tree | c963a8f5411c1ef77fc20ae91ac86144618458ec | |
| parent | 66f36c3686762d9a6e48b0453fc7221be36a0eb8 (diff) | |
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
| -rw-r--r-- | sys/net/if_bridge.c | 22 |
1 files 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); |
