* bridge_output: * * Send output from a bridge member interface. This * performs the bridging function for locally originated * packets. * * The mbuf has the Ethernet header already attached. We must * enqueue or free the mbuf before returning. */
| 2045 | * enqueue or free the mbuf before returning. |
| 2046 | */ |
| 2047 | static int |
| 2048 | bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa, |
| 2049 | struct rtentry *rt) |
| 2050 | { |
| 2051 | struct ether_header *eh; |
| 2052 | struct ifnet *bifp, *dst_if; |
| 2053 | struct bridge_softc *sc; |
| 2054 | uint16_t vlan; |
| 2055 | |
| 2056 | NET_EPOCH_ASSERT(); |
| 2057 | |
| 2058 | if (m->m_len < ETHER_HDR_LEN) { |
| 2059 | m = m_pullup(m, ETHER_HDR_LEN); |
| 2060 | if (m == NULL) |
| 2061 | return (0); |
| 2062 | } |
| 2063 | |
| 2064 | eh = mtod(m, struct ether_header *); |
| 2065 | sc = ifp->if_bridge; |
| 2066 | vlan = VLANTAGOF(m); |
| 2067 | |
| 2068 | bifp = sc->sc_ifp; |
| 2069 | |
| 2070 | /* |
| 2071 | * If bridge is down, but the original output interface is up, |
| 2072 | * go ahead and send out that interface. Otherwise, the packet |
| 2073 | * is dropped below. |
| 2074 | */ |
| 2075 | if ((bifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { |
| 2076 | dst_if = ifp; |
| 2077 | goto sendunicast; |
| 2078 | } |
| 2079 | |
| 2080 | /* |
| 2081 | * If the packet is a multicast, or we don't know a better way to |
| 2082 | * get there, send to all interfaces. |
| 2083 | */ |
| 2084 | if (ETHER_IS_MULTICAST(eh->ether_dhost)) |
| 2085 | dst_if = NULL; |
| 2086 | else |
| 2087 | dst_if = bridge_rtlookup(sc, eh->ether_dhost, vlan); |
| 2088 | /* Tap any traffic not passing back out the originating interface */ |
| 2089 | if (dst_if != ifp) |
| 2090 | ETHER_BPF_MTAP(bifp, m); |
| 2091 | if (dst_if == NULL) { |
| 2092 | struct bridge_iflist *bif; |
| 2093 | struct mbuf *mc; |
| 2094 | int used = 0; |
| 2095 | |
| 2096 | bridge_span(sc, m); |
| 2097 | |
| 2098 | CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { |
| 2099 | dst_if = bif->bif_ifp; |
| 2100 | |
| 2101 | if (dst_if->if_type == IFT_GIF) |
| 2102 | continue; |
| 2103 | if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0) |
| 2104 | continue; |
nothing calls this directly
no test coverage detected