* bridge_broadcast: * * Send a frame to all interfaces that are members of * the bridge, except for the one on which the packet * arrived. * * NOTE: Releases the lock on return. */
| 2536 | * NOTE: Releases the lock on return. |
| 2537 | */ |
| 2538 | static void |
| 2539 | bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, |
| 2540 | struct mbuf *m, int runfilt) |
| 2541 | { |
| 2542 | struct bridge_iflist *dbif, *sbif; |
| 2543 | struct mbuf *mc; |
| 2544 | struct ifnet *dst_if; |
| 2545 | int used = 0, i; |
| 2546 | |
| 2547 | NET_EPOCH_ASSERT(); |
| 2548 | |
| 2549 | sbif = bridge_lookup_member_if(sc, src_if); |
| 2550 | |
| 2551 | /* Filter on the bridge interface before broadcasting */ |
| 2552 | if (runfilt && (PFIL_HOOKED_OUT(V_inet_pfil_head) |
| 2553 | #ifdef INET6 |
| 2554 | || PFIL_HOOKED_OUT(V_inet6_pfil_head) |
| 2555 | #endif |
| 2556 | )) { |
| 2557 | if (bridge_pfil(&m, sc->sc_ifp, NULL, PFIL_OUT) != 0) |
| 2558 | return; |
| 2559 | if (m == NULL) |
| 2560 | return; |
| 2561 | } |
| 2562 | |
| 2563 | CK_LIST_FOREACH(dbif, &sc->sc_iflist, bif_next) { |
| 2564 | dst_if = dbif->bif_ifp; |
| 2565 | if (dst_if == src_if) |
| 2566 | continue; |
| 2567 | |
| 2568 | /* Private segments can not talk to each other */ |
| 2569 | if (sbif && (sbif->bif_flags & dbif->bif_flags & IFBIF_PRIVATE)) |
| 2570 | continue; |
| 2571 | |
| 2572 | if ((dbif->bif_flags & IFBIF_STP) && |
| 2573 | dbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) |
| 2574 | continue; |
| 2575 | |
| 2576 | if ((dbif->bif_flags & IFBIF_DISCOVER) == 0 && |
| 2577 | (m->m_flags & (M_BCAST|M_MCAST)) == 0) |
| 2578 | continue; |
| 2579 | |
| 2580 | if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0) |
| 2581 | continue; |
| 2582 | |
| 2583 | if (CK_LIST_NEXT(dbif, bif_next) == NULL) { |
| 2584 | mc = m; |
| 2585 | used = 1; |
| 2586 | } else { |
| 2587 | mc = m_dup(m, M_NOWAIT); |
| 2588 | if (mc == NULL) { |
| 2589 | if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1); |
| 2590 | continue; |
| 2591 | } |
| 2592 | } |
| 2593 | |
| 2594 | /* |
| 2595 | * Filter on the output interface. Pass a NULL bridge interface |
no test coverage detected