diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 6a49249..05ddcbd 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1642,31 +1642,33 @@ bridge_input(struct ifnet *ifp, struct mbuf *m) /* A 'fast' path for packets addressed to interfaces that are * part of this bridge. */ if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 - && bif->bif_state == BSTP_IFSTATE_FORWARDING) { - LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { + && (!(bif->bif_flags & IFBIF_STP) || bif->bif_state == BSTP_IFSTATE_FORWARDING)) { + struct bridge_iflist *_bif = bif; + + LIST_FOREACH(_bif, &sc->sc_iflist, bif_next) { /* It is destined for us. */ - if (memcmp(CLLADDR(bif->bif_ifp->if_sadl), + if (memcmp(CLLADDR(_bif->bif_ifp->if_sadl), eh->ether_dhost, ETHER_ADDR_LEN) == 0 #if NCARP > 0 - || (bif->bif_ifp->if_carp - && carp_ourether(bif->bif_ifp->if_carp, + || (_bif->bif_ifp->if_carp + && carp_ourether(_bif->bif_ifp->if_carp, eh, IFT_ETHER, 0) != NULL) #endif /* NCARP > 0 */ ) { - m->m_pkthdr.rcvif = bif->bif_ifp; - if (bif->bif_flags & IFBIF_LEARNING) + m->m_pkthdr.rcvif = _bif->bif_ifp; + if (_bif->bif_flags & IFBIF_LEARNING) bridge_rtupdate(sc, eh->ether_shost, ifp, 0, IFBAF_DYNAMIC); - ether_input (bif->bif_ifp, m); + ether_input (_bif->bif_ifp, m); return; } /* We just received a packet that we sent out. */ - if (memcmp(CLLADDR(bif->bif_ifp->if_sadl), + if (memcmp(CLLADDR(_bif->bif_ifp->if_sadl), eh->ether_shost, ETHER_ADDR_LEN) == 0 #if NCARP > 0 - || (bif->bif_ifp->if_carp - && carp_ourether(bif->bif_ifp->if_carp, + || (_bif->bif_ifp->if_carp + && carp_ourether(_bif->bif_ifp->if_carp, eh, IFT_ETHER, 1) != NULL) #endif /* NCARP > 0 */ ) { @@ -1732,6 +1734,7 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, int used = 0; LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { + int _used = 0; dst_if = bif->bif_ifp; if (bif->bif_flags & IFBIF_STP) { @@ -1751,7 +1754,7 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, if (LIST_NEXT(bif, bif_next) == NULL) { mc = m; - used = 1; + _used = 1; } else { mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); if (mc == NULL) { @@ -1763,7 +1766,7 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, if (dst_if != src_if) bridge_enqueue(sc, dst_if, mc, 1); else - used = 0; + _used = 0; mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); if (mc == NULL) { sc->sc_if.if_oerrors++; @@ -1771,6 +1774,9 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, } mc->m_pkthdr.rcvif = dst_if; ether_input (dst_if, mc); + + if (_used) + used = 1; } if (used == 0) m_freem(m);