| 1740 | } |
| 1741 | |
| 1742 | static int |
| 1743 | tunwrite_l2(struct tuntap_softc *tp, struct mbuf *m, |
| 1744 | struct virtio_net_hdr_mrg_rxbuf *vhdr) |
| 1745 | { |
| 1746 | struct epoch_tracker et; |
| 1747 | struct ether_header *eh; |
| 1748 | struct ifnet *ifp; |
| 1749 | |
| 1750 | ifp = TUN2IFP(tp); |
| 1751 | |
| 1752 | /* |
| 1753 | * Only pass a unicast frame to ether_input(), if it would |
| 1754 | * actually have been received by non-virtual hardware. |
| 1755 | */ |
| 1756 | if (m->m_len < sizeof(struct ether_header)) { |
| 1757 | m_freem(m); |
| 1758 | return (0); |
| 1759 | } |
| 1760 | |
| 1761 | eh = mtod(m, struct ether_header *); |
| 1762 | |
| 1763 | if (eh && (ifp->if_flags & IFF_PROMISC) == 0 && |
| 1764 | !ETHER_IS_MULTICAST(eh->ether_dhost) && |
| 1765 | bcmp(eh->ether_dhost, IF_LLADDR(ifp), ETHER_ADDR_LEN) != 0) { |
| 1766 | m_freem(m); |
| 1767 | return (0); |
| 1768 | } |
| 1769 | |
| 1770 | if (vhdr != NULL && virtio_net_rx_csum(m, &vhdr->hdr)) { |
| 1771 | m_freem(m); |
| 1772 | return (0); |
| 1773 | } |
| 1774 | |
| 1775 | /* Pass packet up to parent. */ |
| 1776 | CURVNET_SET(ifp->if_vnet); |
| 1777 | NET_EPOCH_ENTER(et); |
| 1778 | (*ifp->if_input)(ifp, m); |
| 1779 | NET_EPOCH_EXIT(et); |
| 1780 | CURVNET_RESTORE(); |
| 1781 | /* ibytes are counted in parent */ |
| 1782 | if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); |
| 1783 | return (0); |
| 1784 | } |
| 1785 | |
| 1786 | static int |
| 1787 | tunwrite_l3(struct tuntap_softc *tp, struct mbuf *m) |
no test coverage detected